【问题标题】:HashSet storing equal objectsHashSet 存储相等的对象
【发布时间】:2013-03-21 06:58:01
【问题描述】:

以下是从对象列表中查找重复对象的代码。但是由于某种原因,哈希集甚至存储了相等的对象。

我当然在这里遗漏了一些东西,但是当我检查 hashset 的大小时,结果是 5。

import java.util.ArrayList;
import java.util.HashSet;


public class DuplicateTest {

public static void main(String args[]){
    ArrayList<Dog> dogList = new ArrayList<Dog>();
    ArrayList<Dog> duplicatesList = new ArrayList<Dog>();
    HashSet<Dog> uniqueSet = new HashSet<Dog>();

    Dog a = new Dog();
    Dog b = new Dog();
    Dog c = new Dog();
    Dog d = new Dog();
    Dog e = new Dog();

    a.setSize("a");
    b.setSize("b");
    c.setSize("c");
    d.setSize("a");
    e.setSize("a");

    dogList.add(a);
    dogList.add(b);
    dogList.add(c);
    dogList.add(d);
    dogList.add(e);

    if(a.equals(d)){
        System.out.println("two dogs are equal");
    }
    else System.out.println("dogs not eqal");

    for(Dog dog : dogList){
        uniqueSet.add(dog);
    }

    System.out.println("number of unique dogs="+ uniqueSet.size());
    /*for(Dog dog:uniqueSet){
        System.out.println("uniqueset ="+dog.getSize());
    }

    for(Dog dog : duplicatesList){
        System.out.println("duplicate dog="+dog.getSize());
    }*/

}

}

这里是 Dog 类

public class Dog implements Animal, Comparable<Dog>{

String size;

public void makeNoise(){
    System.out.println("woof woof");
}

public String getSize() {
    return size;
}

public void setSize(String size) {
    this.size = size;
}

public int compareTo(Dog d){
    return this.size.compareTo(d.size);
}

public boolean equals(Dog d){
    return this.size.equals(d.size);
}

@Override
public int hashCode() {
    // TODO Auto-generated method stub
    return super.hashCode();
}
}

【问题讨论】:

    标签: java equals hashset duplicate-removal


    【解决方案1】:

    此代码不能满足您的需要:

    public boolean equals(Dog d){
        return this.size.equals(d.size);
    }
    

    这不是覆盖 Object.equals,这是 HashSet 使用的。你需要:

    @Override
    public boolean equals(Object d){ 
        if (!(d instanceof Dog)) {
            return false;
        }
        Dog dog = (Dog) d;
        return this.size.equals(dog.size);
    }
    

    请注意,通过使用 @Override 注释,您要求编译器验证您实际上是在覆盖一个方法。

    编辑:如上所述,您还需要以与您的equals 方法兼容的方式覆盖hashCode。鉴于您正在根据大小检查相等性,最简单的选择是:

    @Override
    public int hashCode() {
        return size.hashCode();
    }
    

    【讨论】:

    • 此外,OP 必须以不同的方式覆盖hashCode,因为就像他现在所做的那样,两个大小相同的不同 Dogs 具有不同的 HashCode。由于 OP 似乎对狗的大小使用一个字符串,一种可能性是使用 return size.charAt(0);
    • @halex:是的,没有发现。会编辑。 (但我不打算只使用charAt(0)...不妨使用大小哈希码...)
    • 您的解决方案只使用size 的哈希码更好我不得不承认:)。 +1
    • hmmm....为什么需要实现 hashCode() 方法。如果我的代码说如果满足此条件,则两个对象相等,那么为什么编译器要检查 hashCode?我了解 HashMaps 中 hashCode 的重要性,但为什么要设置?
    • @antnewbee:你正在使用HashSet。线索在Hash 部分:) 如果您使用TreeSet,它将使用compareTo...但您使用的是HashSet,它基于简单的相等/散列。 (而且它不是调用hashCode 的编译器 - 它是HashSet 中的代码。)
    猜你喜欢
    • 2015-01-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-05-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多