Java 关于hashset、hashmap、hashcode、equals的混淆
集合的属性是它不允许重复元素Java 关于hashset、hashmap、hashcode、equals的混淆,java,hashcode,hashset,scjp,Java,Hashcode,Hashset,Scjp,集合的属性是它不允许重复元素 但参考SCJP:当使用hashset或linkedhashset时。添加对象时,必须覆盖哈希代码,否则可能会在集合中产生重复的元素 boolean[] b=new boolean[5]; Set s=new HashSet(); b[0]=s.add("a"); b[1]=s.add("a"); 这里的输出是True,False 我想知道,当您没有重写hashcode时,为什么输出为false。 但是当您重写hashcode时,必须重写equals() 集合接口是
但参考SCJP:当使用hashset或linkedhashset时。添加对象时,必须覆盖哈希代码,否则可能会在集合中产生重复的元素
boolean[] b=new boolean[5];
Set s=new HashSet();
b[0]=s.add("a");
b[1]=s.add("a");
这里的输出是True,False
我想知道,当您没有重写hashcode时,为什么输出为false。
但是当您重写hashcode时,必须重写equals()
集合接口是否提供默认的equals()方法
我无法理解,首先,
String
确实覆盖了hashCode
和等于,因此您的代码使用了String
的这些方法版本(因为您正在将String
添加到哈希集
)
其次,即使它没有,在您的示例中,“a”是interned,因此对s.add(“a”)的两个调用都添加了完全相同的对象,因此,即使是Object
的hashCode
和equals
的默认实现也会给出相同的结果。您正在添加两个java.lang.String
,Sun/Oracle类已经为其提供了fitting.hashCode()
和.equals()
方法:-)
注意:不是集合需要equals和hash方法,而是您放入其中的对象
如果要将YourOwnClass
对象添加到JDK集合中,则必须明智地重写这两种方法。考虑到这一点,<代码> YourOwnClass < /C> >返回到<代码> java .Lang.Objult<代码>的方法:点:
class YourOwnClass
{
String a;
public YourOwnClass(String a) { this.a = a; }
}
public void testYourOwnClass() throws Exception
{
Set<YourOwnClass> set = new HashSet<YourOwnClass>();
System.out.println( set.add( new YourOwnClass( "b" ) ) );
System.out.println( set.add( new YourOwnClass( "b" ) ) );
}
瞧,这次是“真假”
干杯
集合接口是否提供默认的equals()方法
默认情况下,hashCode()
方法在equals()
中使用,该方法在Object
类本身中定义
对于某些类,例如String
,equals()
检查字符是否相等
检查方法的源代码
如果项已添加到集合中
,则返回false
,否则返回true
,如中所述。确定。。开始
当使用hashset或linkedhashset时。
LinkedhashSet
维护插入元素的顺序,HashSet
不维护插入元素的顺序
我想知道为什么输出是假的
add()
方法在添加元素时返回true(当元素在集合中不存在时。因此,在您的情况下,第一次在集合中不存在“a”),因此第一次返回true。第二次,“a”将已经存在,因此它将返回false
接下来,默认情况下,所有对象都有hashCode()
和equals()
实现。您必须覆盖它们才能更改默认行为。第一件事-我完全同意上面关于LinkedHashset的回答。此外,您可能还不了解.add()方法实际返回的内容,即在返回布尔结果之前检查的内容
另外,这是JavaBeans中的标准之一,您应该重写hashcode()和equals(),以避免错误的结果-请参阅
请记住,您使用的是HashSet,对于HashSet,equals()
和hashCode()
方法继承自AbstractSet。AbstractSet是一个抽象类,HashSet对其进行了扩展,不需要实现任何抽象方法。因为equals()和hashCode()已经实现,所以下面代码的结果是true和false。我使用scope{}
操作符将它们分开,以提高清晰度
public static void main (String[] args) throws java.lang.Exception
{
{ boolean[] b = new boolean[5];
Set s = new HashSet();
b[0]=s.add(new Integer(2));
b[1]=s.add(new Integer(2));
System.out.println("Using Hashset Integers b0 = "+b[0]+" and b1 = "+b[1]);
}
{
boolean[] b=new boolean[5];
Set s=new HashSet();
b[0]=s.add(2);
b[1]=s.add(2);
System.out.println("Using Hashset int b0 = "+b[0]+" and b1 = "+b[1]);
}
}
我相信对于int
和Integer
hashCode()和equals(),Java总是会对它们进行排序。你不必为此担心。我使用Spring框架实现了一个数据服务器,其中我需要自己的实体类,为了确保可以将实体bean对象保存到HashMap中,我必须重写实体定义类中的equals()和hashCode()。如果您使用Eclipse,您可以使用autogenerator为您提供hashCode()和equals()的框架,然后可以对其进行编辑以满足您的需要。String
会覆盖hashCode
。boolean[]b=new boolean[5];Set s=新的HashSet();b[0]=s.add(新整数(2));b[1]=s.add(新整数(2))//输出结果是什么?@SagarByali Integer还覆盖hashCode和equals.boolean[]b=新布尔[5];Set s=新的HashSet();b[0]=s.add(2);b[1]=s.add(2)//输出结果是什么?@SagarByali-true和false。int将被装箱为整数,因此行为将与您之前的注释相同。有没有任何方法,我们可以将此返回设置为TRUE和TRUE?我知道字符串、日期、日历、包装器都有默认的hashcode和equals。但我的问题是:hashset和linkedhashset是否也在同一个括号内(因为它们是从集合扩展而来的)(字符串、日期、日历、包装器、hashset、linkedhashset)。但这张地图不是从科罗拉多州传来的。我不清楚你的问题。这取决于要添加到集合中的对象。它使用所添加项的equals()
和hashCode()
。您的问题是,当覆盖hashCode()
时,为什么要覆盖equals()
?如果您添加字符串对象或包装对象(它们已经有hashCode和eqauls),但如果您添加一个基元:boolean[]b=new boolean[5];Set s=新的HashSet();b[0]=s.add(2);b[1]=s.add(2)//输出是否为True和True?否将是True
然后False
只是澄清-LinkedHashSet保持插入顺序,而不是任何自然的值顺序。我想这就是你的意思,但这可能会让一些人感到困惑。我的意思是一样的:)boolean[]b=新的boolean[5];Set s=新的HashSet();b[0]=s.add(新整数(2));b[1]=s.add(新的
public static void main (String[] args) throws java.lang.Exception
{
{ boolean[] b = new boolean[5];
Set s = new HashSet();
b[0]=s.add(new Integer(2));
b[1]=s.add(new Integer(2));
System.out.println("Using Hashset Integers b0 = "+b[0]+" and b1 = "+b[1]);
}
{
boolean[] b=new boolean[5];
Set s=new HashSet();
b[0]=s.add(2);
b[1]=s.add(2);
System.out.println("Using Hashset int b0 = "+b[0]+" and b1 = "+b[1]);
}
}