[英]Get unique items from List of Objects with a Set in Java
我的人对象看起来像这样
class People {
this.name,
this.height,
this.age
}
我有一个像这样的数据库查询列表
List<People> people = DAO.queryAllPeople();
返回100个人
那我只想要身高独特的人
Set<People> uniquePeople = list
.stream()
.map(people -> people)
.filter(Objects::nonNull)
.collect( Collectors.toSet() );
但这返回了所有对象,是否有办法使人的身高与众不同?
编辑这是我想要的,但是我想要Person对象,以便在遍历它时可以调用get方法
Set<String> people = people
.stream()
.map(People::getHeight)
.filter(Objects::nonNull)
.collect( Collectors.toSet() );
首先,给班级命名People
是不自然的,更好的名字应该是Person
。
因此,为了解决您的问题,您只能像这样覆盖equals
和hashcode
来获取height
:
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Person person = (Person) o;
return height == person.height;
}
@Override
public int hashCode() {
return height;
}
上面假设height是一个int
字段。 如果是Integer
,那么您需要像这样实现它:
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Person person = (Person) o;
return height != null ? height.equals(person.height) : person1.height == null;
}
@Override
public int hashCode() {
return height != null ? height.hashCode() : 0;
}
现在,您可以执行以下操作:
Set<People> uniquePeople =
myList.stream()
.filter(Objects::nonNull)
.collect(Collectors.toSet());
或由于什么原因您不想覆盖equals
和hashcode
您可以使用toMap
收集器完成 。
Set<Person> values = new HashSet<>(myList.stream()
.collect(Collectors.toMap(Person::getHeight, Function.identity(),
(left, right) -> left))
.values());
解密以上代码片段:
myList.stream()
.collect(Collectors.toMap(Person::getHeight, Function.identity(),
(left, right) -> left))
.values()
这会从myList
创建一个流,将myList
收集到地图实现中,其中Person::getHeight
是一个提取地图键的人高的Function.identity()
, Function.identity()
是一个提取地图值的人对象的函数(left, right) -> left)
被称为合并功能,这意味着如果两个给定的人具有相同的键(高度),我们将返回第一个人( left
)。 相反,在按键冲突的情况下, (left, right) -> right
将返回最后一个人。
最后,我们将此处理结果传递给HashSet
构造函数以创建Set<Person>
。
将此任务分为两个子任务。
身高第一组的人:
Map<Integer, List<People>> groups = list.stream()
.collect(Collectors.groupingBy(People::getHeight);
然后找到哪些组只有一个人:
groups.entrySet().stream()
.filter(e -> e.getValue().size() == 1) // use only groups with one person
.map(e -> e.getValue().get(0))
.collect(Collectors.toList());
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.