我有一个 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()
后的原因吗?在 Wrapper
类distinct()
有效吗?
最佳答案
答案就在DistinctOps
类中。方法makeRef
用于返回 ReferencePipeline
的实例包含不同的元素。此方法利用LinkedHashSet
用于执行 reduce
操作以获得不同的元素。请注意LinkedHashSet
从 HashSet
延伸它使用 HashMap
用于存储元素。现在订购 HashMap
为了正常工作,您应该提供 hashCode()
的实现它遵循 hashCode()
之间的正确契约(Contract)和equals()
因此,需要您提供 hasCode()
的实现这样Stream#distinct()
工作正常。
关于java - 为什么java中Object.equals(Object o)需要Object.hashCode()?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51049359/