为什么StringBuffer / StringBuilder不覆盖对象的equals(),hashcode()方法?
请为我建议清晰的图片,以帮助理解问题...
因为StringBuffer是可变的,所以它的主要用途是构造字符串。如果要比较内容,请调用StringBuffer#toString()并比较返回的值。
通常,对可变对象覆盖hashCode()并没有用,因为修改在HashMap中用作键的对象可能会导致存储的值"丢失"。
Mutable在这里意味着什么?
如果您不了解基本原理,请进行一些研究:stackoverflow.com/questions/3554192/
出于所有应有的尊重,我不同意您的声明通常,对可变对象覆盖hashCode()通常没有用...
@Shahzeb如何使用可变对象hashCode()的示例如何?
对我来说,第一个显而易见的参考点是任何ORM类,因此这是来自休眠的链接,并且在SO stackoverflow.com/questions/5031614/
@MattBall先生,您能用您在答案中谈论的hashmap示例来详细说明您的答案。我很清楚你的意思,但是我还是有点困惑:(
@PrinceVijayPratap的简短答案是,与StringBuffer / StringBuilder相比,String是在Map中使用的更好的键。
@MattBall好吧,我明白了为什么它是更好的钥匙:)
实际上,这一切都取决于哈希码值。为了理解这个概念,让我们举个例子:
String str1 = new String("sunil");
String str2 = new String("sunil");
HashMap hm = new HashMap()
hm.put(str1,"hello");
hm.put(str2,"bye");
最后的hm:
hm = { sunil=bye }
在上面的代码中,str1和str2是两个不同的String对象。是否应该将它们分别添加到HashMap?答案是不。这是因为在将值插入/放入HashMap之前,它会内部检查并比较str1,str2的hashCode值。两者都返回相同的哈希码值,因为String类重写equals()和hashcode()方法。因此,在执行hm.put(str2,"bye");后,第一个键将被新值覆盖。现在尝试:
StringBuilder sb1 = new StringBuilder("sunil");
StringBuilder sb2 = new StringBuilder("sunil");
HashMap hm = new HashMap()
hm.put(sb1,"hello");//sb1 and sb2 will return different HashCode
hm.put(sb2,"bye");// StringBuffer/StringBuilder does not override hashCode/equals methods
最后的hm:
{sunil=hello, sunil=bye}
这两个值都将添加到hashMap中,因为sb1和sb2都返回不同的哈希码。 StringBuilder / StringBuffer不会覆盖equals()和hashCode()方法。
Sun Microsystem希望程序员允许在Hashtable或其他任何Hash集合(如HashSet,HashMap…)中添加2种不同的String类型的值,这就是未在StringBuffer,StringBuilder类中故意覆盖hashCode()和equals()的原因。
Sun Microsystem wanted the programmer to allow adding 2 different String kind of Values in Hashtable ...事实并非如此,Hashtable和Map的javadocs积极劝阻使用带有损坏的equalshashcode协定的对象作为键。将StringBuilder对象存储在映射中没有用,因为除非拥有原始对象,否则您将无法通过键获取值。
因为StringBuffer是可变的。以示例尝试一下:)
package test;
import java.util.HashMap;
public class CheckHashcodeEquals {
public static void main(String[] args) {
/*
* String class override equals() and hashcode() method thats way
* override value of HashMap
*/
String s1 = new String("Arya");
String s2 = new String("Arya");
HashMap hm = new HashMap<>();
hm.put(s1,"A1");
hm.put(s2,"A2");
System.out.println(hm); /* Output: {Arya=A2} */
/*
* String class does not override equals() and hashcode() method thats
* way insert duplicate value
*/
StringBuffer sb1 = new StringBuffer("Arya");
StringBuffer sb2 = new StringBuffer("Arya");
HashMap hm2 = new HashMap<>();
hm2.put(sb1,"A1");
hm2.put(sb2,"A2");
System.out.println(hm2); /* Output: {Arya=A2, Arya=A1} */
}
}
此示例说明StringBuffer不会覆盖equals和hashcode,但是没有显示原因。答案本身(Because StringBuffer is mutable)是从较早的答案中复制的。