比较两个类的列表而不迭代列表

时间:2013-10-09 02:47:51

标签: java collections hashcode

我有一个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}));

我如何比较上面两个列表有/无迭代每个列表。还有更好的方法来覆盖哈希码,因此具有相同属性(值和顺序)的两个类应该相等。

2 个答案:

答案 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的两个实例是否相等。

如果您想比较两个列表list1list2,遗憾的是您无法简单地进行

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

SetHashSetSet)的问题在于,它不会包含几个彼此相等的对象。保证对象在集合中是唯一的。例如,如果您在第二个集合中添加新的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()在其整个生命周期内应该是相同且一致的。因此,基于其实例变量的值生成哈希码不是一个好的选择,因为当实例变量值发生变化时,可能会生成不同的哈希码。