为什么Object.equals(Object o)在java中需要Object.hashCode()?
我有一个类型为为什么Object.equals(Object o)在java中需要Object.hashCode()?,java,java-8,java-stream,distinct,hashcode,Java,Java 8,Java Stream,Distinct,Hashcode,我有一个类型为Person的对象列表,我希望使用流除去具有相同名称的元素。我在互联网上发现了使用包装器类的建议,到目前为止,我的代码如下所示: List<Person> people = Arrays.asList(new Person("Kowalski"), new Person("Nowak"), new Person("Big"),
Person
的对象列表,我希望使用流除去具有相同名称的元素。我在互联网上发现了使用包装器类的建议,到目前为止,我的代码如下所示:
List<Person> people = Arrays.asList(new Person("Kowalski"),
new Person("Nowak"),
new Person("Big"),
new Person("Kowalski"));
List<Person> distPeople = people.stream()
.map(Wrapper::new)
.distinct()
.map(Wrapper::unwrap)
.collect(Collectors.toList());
添加以下内容后,包装器
类的实现将起作用:
@Override
public int hashCode()
{
return person.getName().hashCode();
}
有人能解释一下为什么在重写包装器中的hashCode()
类distinct()
后会起作用吗
通常有必要在任何时候重写hashCode方法
覆盖equals方法,以维护总合同
对于hashCode方法,该方法声明相等的对象必须具有
相等的散列码
请阅读equals Java doc中有关合同的详细信息
通常有必要在任何时候重写hashCode方法
覆盖equals方法,以维护总合同
对于hashCode方法,该方法声明相等的对象必须具有
相等的散列码
请阅读有关合同的详细信息答案在课程的DistinctOps
中。方法makeRef
用于返回包含不同元素的ReferencePipeline
的实例。此方法利用LinkedHashSet
执行reduce
操作以获得不同的元素。请注意,LinkedHashSet
扩展自使用HashMap
存储元素的HashSet
。现在,为了使HashMap
正常工作,您应该提供hashCode()
的实现,它遵循hashCode()
和equals()
之间的正确约定,因此,需要为hasCode()
提供一个实现,以便Stream#distinct()
工作正常。答案在于类的DistinctOps
。方法makeRef
用于返回包含不同元素的ReferencePipeline
的实例。此方法利用LinkedHashSet
执行reduce
操作以获得不同的元素。请注意,LinkedHashSet
扩展自使用HashMap
存储元素的HashSet
。现在,为了使HashMap
正常工作,您应该提供hashCode()
的实现,它遵循hashCode()
和equals()
之间的正确约定,因此,需要为hasCode()
提供一个实现,以便Stream#distinct()
工作正常。distinct()
操作在内部使用一个哈希集来检查它是否已经处理了某个元素。而HashSet
又依赖于其元素的hashCode()
方法
如果不重写hashCode()
方法,它将返回其默认值,返回对象的标识,这通常在两个对象之间是不同的,即使它们根据equal()
是相同的。因此,HashSet
将它们放入不同的bucket中,并且不能再确定它们是“相同”的对象。distinct()
操作在内部使用一个HashSet
来检查它是否已经处理了某个元素。而HashSet
又依赖于其元素的hashCode()
方法
如果不重写hashCode()
方法,它将返回其默认值,返回对象的标识,这通常在两个对象之间是不同的,即使它们根据equal()
是相同的。因此,HashSet
将它们放入不同的桶中,并且不能再确定它们是“相同”的对象。因为distinct()
可能使用HashSet
来获得最佳性能。您应该始终在实现时实现。无论您是否对对象执行此操作,equals
和hashCode
都应该一起重写,以便产生一致的结果。否则,您就违反了对象
的约定。因为distinct()
可能会使用哈希集
来获得最佳性能。您应该始终在实现时实现。无论您是否对对象执行此操作,equals
和hashCode
都应该一起重写,以便产生一致的结果。否则,您就违反了Object
的合同。似乎您引用了equals()
的javadoc,所以您应该链接到它。但是您没有链接到报价的来源。似乎您引用了equals()
的javadoc,所以您应该链接到它。但是您没有链接到报价的来源。
@Override
public int hashCode()
{
return person.getName().hashCode();
}