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

时间:2012-12-19 12:33:45

标签: 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());

代码将输出

false
true
1

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

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

8 个答案:

答案 0 :(得分:7)

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

关于你上面的两个问题:

鉴于两个对象o1o2(为了简化,我们假设o1!=nullo2!=null),最后,一个搭扣图必须确定它们是否具有相同的价值。 (最终,因为HaspMap还检查o1o2是否具有相同的哈希值,但这在您的问题的上下文中并不重要)。它通过调用方法equals()来完成此操作。只要o1.equals(o2)为false,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() }。

答案 1 :(得分:6)

问题1: - 是否可以保证像地图或集合这样的集合会按照内容而不是参考来比较密钥?

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

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

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

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

首先 - 是Object#hashCode(),用于计算索引。

第二个 - 是Object#equals(),然后使用哈希colision有地方。

答案 2 :(得分:3)

如果您打开java.util.AbstractMap的{​​{3}},则可以看到在任何地方使用Object#equals方法检查键和值等式。实际将在地图内部进行比较的内容取决于Object#equals方法的键/值实现。

答案 3 :(得分:1)

此处Integer是Waraper的最终类,它覆盖equals()方法,因此它只会比较内容。

因此,如果使用Integers是任何包装类,Map

就没有问题

假设您想要使用Custome Class作为密钥您需要覆盖equals() and hashcode()方法以避免Map中的重复

答案 4 :(得分:0)

它实际上取决于您为equals()指定的K /密钥的Map实施。

尝试对Map<Object,String>做同样的事情,看看会发生什么(提示:要使Object相等,他们实际上必须是同一个对象)

干杯

答案 5 :(得分:0)

第一个比较两个不同的对象(参考) - &gt;假的。

第二个比较(等于)这些对象的值 - &gt;真

Hashmap使用对象的equals和hascode方法来确定唯一键。所以你有两次插入相同的键导致一个剩余的元素。第二个。看看Map#put javadoc,看看发生了什么。

答案 6 :(得分:0)

在hashmap的情况下,使用equals()和hashcode()方法比较密钥。

在上面的示例中,hashcode()和equals()都在Integer类中重写。当HashMap比较两个键时,首先它需要该对象的hashcode(),然后在该对象上调用equals方法,并且键具有相同的哈希码值。

答案 7 :(得分:0)

当将项目放入HashMap(和扩展的HashSet)时,使用hashCode(通过简单的线性函数进行转换)来确定项目应放在其内部集合中的位置。

然后在确定的位置使用(o1 == o2 || o1.equals(o2))搜索相同的对象(在那里存储的所有项目中),如果引用不同则调用#equals函数,这是一个简化#equals调用的性能改进。如果找到相同的项目,则其指定的值将替换为新的项目,否则,新项目将简单地添加到内部集合中。