【问题标题】:Hashtable comparator problem哈希表比较器问题
【发布时间】:2010-03-07 16:43:43
【问题描述】:

大家好,我从来没有写过比较器 b4,我遇到了一个真正的问题。我创建了一个哈希表。

Hashtable <String, Objects> ht;

有人可以展示你如何为 Hashtable 编写比较器吗?我见过的例子覆盖了等于和一切,但我根本不知道。下面的代码不是我的,而是我发现的一个例子,哈希表中的关键是我猜我不能这样做。

 public class Comparator implements Comparable<Name> {
        private final String firstName, lastName;

        public void Name(String firstName, String lastName) {
            if (firstName == null || lastName == null)
                throw new NullPointerException();
        this.firstName = firstName;
            this.lastName = lastName;
        }

        public String firstName() { return firstName; }
        public String lastName()  { return lastName;  }

        public boolean equals(Object o) {
            if (!(o instanceof Name))
                return false;
            Name n = (Name)o;
            return n.firstName.equals(firstName) &&
                   n.lastName.equals(lastName);
        }

        public int hashCode() {
            return 31*firstName.hashCode() + lastName.hashCode();
        }

        public String toString() {
        return firstName + " " + lastName;
        }

        public int compareTo(Name n) {
            int lastCmp = lastName.compareTo(n.lastName);
            return (lastCmp != 0 ? lastCmp :
                    firstName.compareTo(n.firstName));
        }
    }

【问题讨论】:

  • 您真的需要比较两个Hashtable 实例,还是哈希表中包含的两个项目?
  • 这比我写过的任何比较器都要长约 100 倍。为什么你需要一个比较器?是什么让你觉得你做的?你的钥匙是什么样子的?
  • 您是否实际实现了您的自定义哈希表,或者您是否在代码中使用了java.util.Hashtable 输入错误(HashTable)?
  • 是的,抱歉,我习惯于使用 Hashtable 进行驼峰式化。我只是按字母顺序比较集合的元素
  • 你到底想要做什么,也就是说,你希望现在它允许你做什么?回答这个问题,我们就能做到帮助你!

标签: java hashtable comparator


【解决方案1】:

比较器会告诉您两个项目中哪一个更大。如果这对您的 HashTable 有意义,那么只有您可以说出其含义。想要以这种方式比较两个 HashTable 是非常不寻常的。

【讨论】:

  • 所以你是说我不应该做一个哈希表?像树集这样的东西会更合适吗?基本上我有一组数据(目前在哈希表中),我想按字母顺序排列
【解决方案2】:

这不是 Comparator 类。那是一个实现 Comparable 的 Name 类。

Hashtable 和 Hashmap 不使用 Comparator 或 Comparable。如果您想要排序的键,请使用 TreeMap。

【讨论】:

    【解决方案3】:

    比较器用于对列表进行排序。 Hashtable(注意大小写)不按其元素排序。你可以通过遍历它的键来订购一个表(如果你想在它的键上订购,我想)并将它们放在List 中。接下来要做的是对List 进行排序并遍历List,然后使用Hashtable 中的get 来获取其关联值。

    这是一个示例(使用HashMap,因为它与Java 集合的其余部分集成得更好。HashMapHashtable 基本相同。):

    public static void main(String... arg) {
        HashMap<String, Object> x = new HashMap<String, Object>();
        x.put("second", " ordered!");
        x.put("first", "Correctly");
    
        LinkedList<String> keys = new LinkedList<String>();
        for(final String f : x.keySet()) {
            keys.add(f);
        }
        Collections.sort(keys, new Comparator<String>() {
            public int compare(String first, String second) {
                // return -1 is "first <  second"
                // return 1  is "first >  second"
                // return 0  is "first == second"
                return first.compareTo(second);
            }
        });
    
        for(final String f : keys) {
            System.out.print(x.get(f));
        }
        System.out.println();
    }
    

    keys 列表的顺序按匿名Comparator 类排序。它将按字母顺序排序,这是字符串的默认值。您可以使用自己的密钥对象,就像您提到的那样。如果你没有在这个关键对象中实现Comparator,那么你可以提供,如上例所示。否则,您可以通过调用使用默认的Comparator

    Collections.sort(keys);
    

    这将使用Comparator 的类实现。如果它没有实现Comparator,那么它会抛出一个异常(因为它会强制转换为Comparator

    【讨论】:

    • 嗨,这太棒了,所以你说使用 Hashmap 而不是 Hashtable。我不明白你为什么要使用链表?
    • 因为HashMap(注意M的大小写)和Hashtable(小t)都不是“有序”的。因此,它们的元素以半随机顺序存储,以提高性能。我使用LinkedList,因为我使用了很多.add(f);,而LinkedList 针对追加/删除进行了优化。然后使用Collections.sortList 进行排序。列表具有内部顺序表示,它是“有序的”,因此HashMap 的键的顺序存储在List 中。遍历 List 将以正确的顺序给出键。
    • 地图 (HashMap) 不对其元素进行排序。键的顺序是由键对象的哈希值决定的,所以不能对 HashMap(或 Hashtable)进行排序。 LinkedList 的重点是按字母顺序对 HashMap 的键进行排序,然后您可以使用此有序列表来获取关联的值。您确定 Hashtable 真的是您想要使用的吗?
    • 如果你想按键排序,为什么不使用TreeMap呢?地图 sortedMap = new TreeMap(comparatorInstance); sortedMap.putAll(hashMap);或者更好的是,从一开始就使用树状图。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-01-25
    • 2011-01-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-10-26
    相关资源
    最近更新 更多