我有一个Abc类,如下所示
public class Abc {
int[] attributes;
Abc(int[] attributes){
this.attributes = attributes;
}
}
覆盖Abc
哈希码,如下所示
@Override
public int hashCode() {
int hashCode = 0;
int multiplier = 1;
for(int i = attributes.length-1 ; i >= 0 ; i++){
hashCode = hashCode+(attributes[i]*multiplier);
multiplier = multiplier*10;
}
return hashCode;
}
我使用上面的类来创建一个对象列表,我想比较两个列表是否相等,即具有相同属性的对象的列表。
List<Abc> list1 ;
list1.add(new Abc(new int[]{1,2,4}));
list1.add(new Abc(new int[]{5,8,9}));
list1.add(new Abc(new int[]{3,4,2}));
List<Abc> list2;
list2.add(new Abc(new int[]{5,8,9}));
list2.add(new Abc(new int[]{3,4,2}));
list2.add(new Abc(new int[]{1,2,4}));
我如何比较上面两个列表有/无迭代每个列表。还有更好的方法来覆盖哈希码,因此具有相同属性(值和顺序)的两个类应该相等。
答案 0 :(得分:1)
您必须覆盖班级equals
中的Abc
功能。如果您使用的是IDE,它可以用来生成足够好的东西。例如,Eclipse生成以下内容:
@Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (obj == null) {
return false;
}
if (getClass() != obj.getClass()) {
return false;
}
Abc other = (Abc) obj;
if (!Arrays.equals(attributes, other.attributes)) {
return false;
}
return true;
}
使用此equals
方法,您现在可以检查Abc
的两个实例是否相等。
如果您想比较两个列表list1
和list2
,遗憾的是您无法简单地进行
boolean listsAreEqual = list1.equals(list2); // will be false
因为这不仅会检查列表中的元素是否相同,而且它们的顺序是否相同。你可以做的是比较两个集合,因为在集合中,元素没有顺序。
boolean setAreEqual = new HashSet<Abc>(list1).equals(new HashSet<Abc>(list2)); // will be true.
请注意,在这种情况下,您应该将hashcode()
的实施保留在Abc
中,以使HashSet
正常运行。作为一般规则,实现equals
的类也应该实现hashcode
。
Set
(HashSet
为Set
)的问题在于,它不会包含几个彼此相等的对象。保证对象在集合中是唯一的。例如,如果您在第二个集合中添加新的new Abc(new int[]{5,8,9})
,则这两个集合仍然相等。
如果它困扰你,那么可能的解决方案是比较两个列表,但事先对它们进行排序(为此你必须提供一个比较器或实现compareTo
),或者使用Guava的HashMultiset ,这是一个无序容器,可以多次包含相同的对象。
答案 1 :(得分:0)
重写equals方法以比较对象。正如评论所提到的,当覆盖equals方法时,你应该重写hashcode方法。
通过这个
这样两个具有相同属性(值和顺序)的类应该相等。
我认为你的意思是两个具有相同属性的对象。
你可以尝试这样的事情
public boolean equals(Object o) {
if(!(Object instanceOf Abc)) {
return false;
}
Abc instance = (Abc)o;
int[] array = instance.attributes;
for(i=0;i<array.length;i++){
if(array[i]!=this.attributes[i]) {
return false;
}
}
}
编辑至于hashcode
,概念就是
object1.equals(object2)
是真的,那么
object1.hashcode()
和
object2.hashcode()
必须返回相同的值。并且对象的hashCode()
在其整个生命周期内应该是相同且一致的。因此,基于其实例变量的值生成哈希码不是一个好的选择,因为当实例变量值发生变化时,可能会生成不同的哈希码。