HashSet包含()方法

时间:2015-07-17 07:27:23

标签: java collections set contains hashset

我执行了下面的代码,发现输出为false

import java.util.Set;
import java.util.HashSet;

public class Name {
    private String first, last;

    public Name(String first, String last) {
        this.first = first;
        this.last = last;
    }

    public boolean equals(Object o) {
        if (!(o instanceof Name))
            return false;
        Name n = (Name) o;
        return n.first.equals(first) && n.last.equals(last);
    }

    public static void main(String[] args) {
        Set<Name> s = new HashSet<Name>();
        s.add(new Name("Donald", "Duck"));
        System.out.println(s.contains(new Name("Donald", "Duck")));
    }
}

我想知道它的行为方式以及输出为false的原因。

6 个答案:

答案 0 :(得分:5)

您还需要覆盖hashCode()方法以及equals()。这两种方法都用于HashSet的正常功能,因此如果您将class作为key,则必须在用户定义的类中覆盖, hashCode()类的其他Object被使用,并且没有两个不同的objects被视为与hashCode()总是不同的false相同,并且肯定会返回{{1}总是在contains()

的情况下

答案 1 :(得分:3)

为了使HashSet(或HashMap,就此而言)正确定位您的对象,您需要覆盖hashCode()方法,以便两个相同的对象具有相同的hashCode。执行此操作的规范方式如下所示(假设firstlast不能null,就像您的equals方法假设:

@Override
public int hashCode() {
    final int prime = 31;
    int result = 1;
    result = prime * result + first.hashCode();
    result = prime * result + last.hashCode();
}

答案 2 :(得分:2)

Java中基于Hash的任何数据结构实现(集合)都基于两件事检查重复:

1:如果equals方法为已存储在集合中的任何元素返回true

2:如果hashCode方法为已存储在集合中的任何元素返回same integer value

所以在你的情况下你没有覆盖hashCode方法,这意味着它将尝试使用hashCode方法检查hashCode相等性Object类的默认实现,它不知道你的lastfirst变量。

我希望它有所帮助。

答案 3 :(得分:1)

您的equals()方法没问题,但您错过了覆盖hashCode()方法,只需覆盖hashCode()方法,它就可以了。并且不要忘记您总是需要覆盖equals() and hashCode()或不覆盖它们以获得正确的行为。如果您计划将对象用作散列机制中的键,则必须覆盖它们。

@Override
public int hashCode() {
    final int prime = 31;
    int result = 1;
    result = prime * result + ((first == null) ? 0 : first.hashCode());
    result = prime * result + ((last == null) ? 0 : last.hashCode());
    return result;
}

答案 4 :(得分:1)

您必须在覆盖hashCode()的每个类中覆盖equals()。如果不这样做,将导致违反Object.hashCode()的一般合同,这将阻止您的课程与所有基于散列的集合(包括HashMap, HashSet, and Hashtable)一起正常运行。

来自Effective Java的

,来自Joshua Bloch

答案 5 :(得分:0)

您还可以查看代码的执行方式。

  1. 当您尝试在集合中添加元素时,它会调用哈希码并获取存储桶。

  2. 从哈希码中获取哈希值后,将为所有具有相同哈希令牌的人运行覆盖的等号。

  3. 希望这有帮助。