0

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

如何在迭代每个列表的情况下比较上述两个列表。还有没有更好的方法来覆盖 hashcode ,以便具有相同属性(值和顺序)的两个类应该相等。

4

2 回答 2

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()in的实现Abc,以HashSet使其正常运行。作为一般规则,实现的类也equals应该实现hashcode

Set( HashSetare )的问题Set在于,根据设计,它不会包含多个彼此相等的对象。保证对象在集合中是唯一的。例如,如果您new Abc(new int[]{5,8,9})在第二个集合中添加一个新的,那么这两个集合仍然是相等的。

如果它困扰你,那么可能的解决方案是比较两个列表,但在事先对它们进行排序之后(为此你必须提供一个比较器或实现compareTo),或者使用 Guava 的HashMultiset,它是一个可以包含相同对象的无序容器多次。

于 2013-10-09T03:04:42.220 回答
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()一个对象应该在它的整个生命周期中是相同和一致的。因此,根据其实例变量的值生成哈希码并不是一个好的选择,因为当实例变量值发生变化时,可能会生成不同的哈希码。

于 2013-10-09T02:54:58.223 回答