我只想确保我的代码安全,使用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的行为很感兴趣。
HashMap
?答案 0 :(得分:7)
调用方法equals
,因此它是被比较的内容。
关于你上面的两个问题:
鉴于两个对象o1
和o2
(为了简化,我们假设o1!=null
和o2!=null
),最后,一个搭扣图必须确定它们是否具有相同的价值。 (最终,因为HaspMap
还检查o1
和o2
是否具有相同的哈希值,但这在您的问题的上下文中并不重要)。它通过调用方法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创建树图,则使用比较器)。
因此,保证在HashMap
和HashSet
中,方法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调用的性能改进。如果找到相同的项目,则其指定的值将替换为新的项目,否则,新项目将简单地添加到内部集合中。