HashSet重复行为

时间:2015-04-15 04:55:06

标签: java duplicates hashset

我有两个 Person 对象在HasSet中有相同的数据,但我仍然在重复。这是场景。

class Person {

private String fName;
private String lName;

Person(String fName, String lName){
    this.fName = fName;
    this.lName = lName;
}

//getters & setters

@Override
public int hashCode() {
    return (int) fName.hashCode() * lName.hashCode();
}

@Override
public boolean equals(Object o) {
    if(o == null) return false;
    if(!(o instanceof Person)) return false;

    Person  other = (Person) o;
    if(!this.fName.equals(other.fName)) return false;
    if(!this.lName.equals(other.lName)) return false;

    return true;
}
}

public class HashSetDuplicateTest {
public static void main(String[] args){
    Set<Person> pSet = new HashSet<Person>();

    Person p1 = new Person("abc", "efg");
    pSet.add(p1);
    p1.setlName("xyz");

    Person p2 = new Person("abc", "xyz");
    pSet.add(p2);

    for(Person p : pSet){
            System.out.println(p.getfName()+" "+p.getlName());
    }
}
}

Output:
"abc xyz"
"abc xyz"

关于HashSet的这种行为的任何想法?如您所见,我有两个Person个对象在HasSet中具有相同的数据,但仍然会重复。

1 个答案:

答案 0 :(得分:1)

Person p1 = new Person("abc", "efg");
pSet.add(p1);
p1.setlName("xyz");

HashSet元素(就像HashMap键一样)应该是不可变的。

如果您更新它们(以影响equalshashCode的方式),那么事情就会中断。

在这种特殊情况下,您最终会在散列桶中找到与其散列码不匹配的Person,以便在插入潜在的新元素(并检查重复项)时找不到它。迭代所有元素时仍然会返回它(因此它确实显示在打印输出中)。