HashSet contains() 方法
Posted
技术标签:
【中文标题】HashSet contains() 方法【英文标题】:HashSet contains() method 【发布时间】:2015-10-06 20:40:34 【问题描述】:我执行了下面的代码,发现输出是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
。
【问题讨论】:
你还没有覆盖hashCode
。
【参考方案1】:
您必须在每个覆盖 equals()
的类中覆盖 hashCode()
。否则将导致违反Object.hashCode()
的一般合同,这将阻止您的类与所有基于哈希的集合一起正常运行,包括HashMap, HashSet, and Hashtable
。
来自 Effective Java,作者:Joshua Bloch
【讨论】:
输入代码格式,每行代码给四个空格【参考方案2】:您还可以查看您的代码将如何执行。
当您尝试在集合中添加元素时,它会调用哈希码并获取存储桶。
一旦您从哈希码中获得哈希值,就会为所有拥有相同哈希令牌的人运行覆盖的等号。
希望这会有所帮助。
【讨论】:
【参考方案3】:Java 中任何基于Hash
的数据结构实现(集合)都基于两件事检查重复:
1 : 如果equals
方法为已存储在集合中的任何元素返回true
。
2 : 如果hashCode
方法为已存储在集合中的任何元素返回same integer value
。
因此,在您的情况下,您没有覆盖 hashCode 方法,这意味着它将尝试使用 Object
类的 hashCode 方法默认实现来检查 hashCode 是否相等,该类不知道您的 last
和 first
变量。
希望对你有帮助。
【讨论】:
【参考方案4】:您的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;
【讨论】:
【参考方案5】:您还需要覆盖hashCode()
方法以及equals()
。这两种方法都用于HashSet
的正确功能,因此如果您将class
设置为key
,则必须在用户定义的类 中覆盖,否则hashCode()
of @ 987654327@ 类正在被使用,没有两个不同的objects
可以被视为相同,因为它们的hashCode()
总是不同的,并且在contains()
的情况下肯定会返回false
always。
【讨论】:
@babanna 如果它消除了你的疑虑,你可以将其标记为正确。【参考方案6】:为了使HashSet
(或HashMap
,就此而言)正确定位您的对象,您需要重写hashCode()
方法,以便两个相等的对象具有相同的hashCode。执行此操作的规范方法如下所示(假设 first
和 last
不能是 null
,就像您的 equals
方法假设:
@Override
public int hashCode()
final int prime = 31;
int result = 1;
result = prime * result + first.hashCode();
result = prime * result + last.hashCode();
【讨论】:
以上是关于HashSet contains() 方法的主要内容,如果未能解决你的问题,请参考以下文章
慎用ArrayList的contains方法,使用HashSet的contains方法代替
HashSet——add remove contains方法底层代码分析(hashCode equals 方法的重写)
Arraylist中contains方法底层实现解读与HashSet自定义类型去重效果的简述(接上一篇)