为什么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();
}