java - 为什么java中Object.equals(Object o)需要Object.hashCode()?

标签 java java-8 java-stream distinct hashcode

我有一个 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());

在文档中据说 distinct()

Returns a stream consisting of the distinct elements (according to Object.equals(Object)) of this stream.

实现Wrapper这不起作用(我用两个 Kowalski 得到相同的流):

public class Wrapper
{
    private final Person person;

    Wrapper(Person p)
    {
        person = p;
    }

    public Person unwrap()
    {
        return person;
    }

    public boolean equals(Object other)
    {
        if(other instanceof Wrapper)
            return ((Wrapper) other).person.getName().equals(person.getName());
        else
            return false;
    }
}

实现Wrapper添加此后类即可工作:

@Override
public int hashCode()
{
    return person.getName().hashCode();
}

有人可以解释一下覆盖 hashCode() 后的原因吗?在 Wrapperdistinct()有效吗?

最佳答案

答案就在DistinctOps类中。方法makeRef用于返回 ReferencePipeline 的实例包含不同的元素。此方法利用LinkedHashSet用于执行 reduce操作以获得不同的元素。请注意LinkedHashSetHashSet 延伸它使用 HashMap用于存储元素。现在订购 HashMap为了正常工作,您应该提供 hashCode() 的实现它遵循 hashCode() 之间的正确契约(Contract)和equals()因此,需要您提供 hasCode() 的实现这样Stream#distinct()工作正常。

关于java - 为什么java中Object.equals(Object o)需要Object.hashCode()?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51049359/

相关文章:

java - 如何将嵌套循环转换为单行循环?

java - 如何使用 Java lambda 将 List<Foo> 收集到 Map<Bar, List<Baz>>?

java - 迭代器与 Java 8 流

java - Java 是否有注释来指出 List 可能包含 null?

java.lang.IllegalArgumentException : The observer is null 异常

java - 引用 CompletableFuture 中的字段,它又可以是 CompletableFuture : java

java - 如何在 Set 中返回一个不同的对象并求和一个公共(public)值?

Java正则表达式替换原始字符串中的组值

java - JFreeChart 渲染器(层)顺序

java - 一个 Java 构建器类,其 JsonDeserialize 可选字段设置为 Optinal.empty。 JsonDeserialize时设置默认值