对于String,StringBuffer,StringBuilder作为HashMap的Key的探讨 | 您所在的位置:网站首页 › hashmap为什么用string做key › 对于String,StringBuffer,StringBuilder作为HashMap的Key的探讨 |
查看源码: 如果查看StringBuffer,它将发现它使用了Object.equals: public boolean equals(Object obj) { return (this == obj); } 而String的实现是: public boolean equals(Object anObject) { if (this == anObject) { return true; } if (anObject instanceof String) { String anotherString = (String)anObject; int n = value.length; if (n == anotherString.value.length) { char v1[] = value; char v2[] = anotherString.value; int i = 0; while (n-- != 0) { if (v1[i] != v2[i]) return false; i++; } return true; } } return false; }接下来是一些争论:争论的中心点在于String的intern()那个技术点; 你可以参考我的文章: https://blog.csdn.net/Hubz131/article/details/105158957如果我的文章不能是你满意,也可以自行搜索;现在,想象一下,如果我有两个具有相同哈希码值的对象,将会发生什么?在这种情况下,HashMap首先需要知道两个对象是否相同,因为如果它们相同,则意味着映射中只有一个条目,并且与该键关联的现有值将被新值替换。但是,仅具有相同的哈希码并不意味着两个密钥都相等。因此,是否相等是通过在关键对象上调用equals()方法来确定的。如果equals()返回true,则对象相等。在这种情况下,哈希映射需要更新现有条目的值。但是如果equals()返回false怎么办?在这种情况下,两个对象都不相同,应将其存储为单独的条目。因此,它们都将存储在HashMap中。 在检索值时,将使用输入值的哈希码到达存储它的隔离专区(即:位桶数组的相应位置),然后,如果隔离专区包含多个对象(由于使用拉链法解决哈希碰撞的原因),则将检查输入键是否与隔离专区中的某个对象相等,如果匹配,则返回关联的值; 仅具有相同的哈希码并不意味着两个密钥都相等: String s1 = new String("uP"); String s2 = new String("v1"); System.out.println(s1.hashCode()); System.out.println(s2.hashCode()); HashMap hm = new HashMap(); hm.put(s1, 1); hm.put(s2, 2); System.out.println(hm.size());现在,让我们将上述理论应用于您拥有的代码。如果字符串对象的内容相等,则它们相等。并且根据规则,如果两个对象相等,则它们应返回相同的哈希码。但是请记住,相反是不正确的。如果两个对象返回相同的哈希码,则内容不一定相等。具有相同内容的两个字符串相等,即使它们在物理上是不同的对象,它们也会返回相同的哈希码,因此在HashMap中用作键时,它们始终会映射到同一条目。因此,就会出现以上现象(指的是例1)。 String类会覆盖默认的equals()方法,该方法表示两个对象如果具有相同的引用,而这些引用依赖于内容的相等性,则它们相等。之所以可以这样做是因为String是不可变的。但是,StringBuffer不会这样做。它仍然依赖于引用相等(地址)。 |
CopyRight 2018-2019 实验室设备网 版权所有 |