SET的属性是它不允许重复的元素。
但引用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时,你必须重写equals()。
DOes Collection接口是否提供默认的equals()方法?
我无法理解,
答案 0 :(得分:3)
您正在添加两个java.lang.String
类,Sun / Oracle已经为您提供了适合.hashCode()
和.equals()
方法的类: - )
注意: 不需要equals和hash方法的集合 - 它是您将放入其中的对象!
如果要将YourOwnClass
个对象添加到JDK集合中,则必须明智地覆盖这两个方法。考虑一下,其中YourOwnClass
回到java.lang.Object
的方法实现:
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" ) ) );
}
这将打印
真
真
尽管我们可以争辩说,从语义角度来看,添加的两个YourOwnClass
对象应该被认为是相同的。
然后,按如下所示修改YourOwnClass
,然后重试。
class YourOwnClass
{
String a;
public YourOwnClass(String a) { this.a = a; }
@Override public int hashCode() { return a.hashCode(); }
@Override public boolean equals(Object obj) { return a.equals( ((YourOwnClass)obj).a ); }
}
Voila - 这次是“真假”!
干杯,
答案 1 :(得分:2)
好的..开始吧。
使用hashset或linkedhashset时。
LinkedhashSet
维护插入元素的顺序,HashSet
不。
我想知道输出是怎么回事
如果添加了元素,则add()
方法返回true(当元素不是已经存在于set.So中时,在您的情况下,第一次出现,&#34; a&#34 ;不存在于集合中),因此它第一次返回true。第二次,&#34; a&#34;已经存在,它将返回false。
接下来,默认情况下,所有对象都有hashCode()
和equals()
实现。您必须覆盖它们才能更改默认行为。
答案 2 :(得分:1)
Collection接口是否提供默认的equals()方法?
默认情况下是,hashCode()
方法用于equals()
类本身中定义的Object
对于某些类,例如String
,equals()
检查字符是否相等。
检查String.equals()方法的源代码
如果已在Set
中添加了项目,则会返回false
,否则返回true
中提到的{{1}}。
答案 3 :(得分:0)
首先,String
会覆盖hashCode
和equals
,因此您的代码会使用String
这些方法的版本(因为您要添加String
}到你的HashSet
)。
其次,即使它没有,在你的例子中,“a”被实习,因此对s.add(“a”)的两次调用都添加完全相同的对象,所以即使Object
<{1}}和hashCode
的默认实现会产生相同的结果。
答案 4 :(得分:0)
首先要做的事情 - 我完全同意并且上面有关于LinkedHashset的+1 @TheLostMind回答。此外,您可能缺乏对.add()方法实际返回的理解,即在返回布尔结果之前检查了什么。
P.S。它是JavaBeans中的标准之一,您应该覆盖hashcode()和equals()以避免错误结果 - 请参阅http://www.xyzws.com/javafaq/why-always-override-hashcode-if-overriding-equals/20
请记住,您正在使用HashSet,而对于HashSet,equals()
和hashCode()
方法是从AbstractSet继承的。 AbstractSet是一个抽象类,HashSet扩展它,不需要实现任何抽象方法。因为equals()和hashCode()已经实现,所以您在下面的代码中看到的结果为true和false。我使用范围{}
运算符将它们分开以提高清晰度。
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 Framework实现了一个dataserver,我需要自己的实体类,并确保我可以将我的Entity bean对象保存到HashMap中,我必须在我的Entity定义类中重写equals()和hashCode()。如果您使用Eclipse,则可以使用autogenerator为您提供hashCode()和equals()的框架,然后可以根据您的需要对其进行编辑。