带有整数键的Java Map:如何比较键?

Sco*_*tus 6 java collections

我只是想确保我的代码使用对象作为键是安全的Integer.这是一个简短的例子:

Integer int1 = new Integer(1337);
Integer int2 = new Integer(1337);

if (int1 == int2) {
    System.out.println("true");
} else {
    System.out.println("false");
}

if (int1.equals(int2)) {
    System.out.println("true");
} else {
    System.out.println("false");
}

Map<Integer, Object> map = new HashMap<Integer, Object>();
map.put(int1, null);
map.put(int2, null);

System.out.println(map.size());
Run Code Online (Sandbox Code Playgroud)

代码将输出

false
true
1
Run Code Online (Sandbox Code Playgroud)

这就是我所期待的,参考文献有所不同,但它们彼此相同.现在我对Map的行为很感兴趣.

  • 是否可以保证像Map或Set这样的集合会按照内容而不是参考来比较密钥?
  • 或者取决于实际的实施,比如HashMap

gef*_*fei 7

equals调用该方法,因此它是被比较的内容.

至于你上面的两个问题:

给定两个对象o1并且o2(为了简化,我们假设o1!=nullo2!=null),最终,hasp map必须确定它们是否具有相同的值.(最终,因为HaspMap还检查o1o2具有相同的哈希值,但这不是重要的在你的问题的情况下).它通过调用方法来完成此操作equals().只要o1.equals(o2)是假,两个对象被认为是两个不同的键HashMap.

HashSet还调用equals()以确定元素是否已包含在集合中,请参阅http://docs.oracle.com/javase/6/docs/api/java/util/HashSet.html#add%28E%29.

TreeMap另一方面,必须比较两个对象,并确定它们是否相等,或者哪个更大.它通过调用来做到这一点compareTo().因此,它的返回值o1.compareTo(o2)很重要(或者,如果您使用构造函数http://docs.oracle.com/javase/6/docs/api/java/util/TreeMap.html#TreeMap创建了树映射%28java.util.Comparator%29,使用比较器).

因此,所保证的是,在HashMapHashSet,该方法equals()是用来分辨物体,并在TreeMap的方法compareTo().


Dam*_*ash 6

Q1: - 是否可以保证像Map或Set这样的集合会按照内容而不是参考来比较密钥?

A1: - No.Collection,Map and Set是接口.他们所保证的只是可能方法的契约.

Q2: - 取决于HashMap的实际实现?

A2:是的.课程是如何处理比较的,这是开发者的决定.

HashMap使用两件事来分配它们的对象

首先 - 是Object#hashCode(),用于计算指数.

第二 - 是Object#equals(),那就是使用哈希colision有地方.