我的人员对象看起来像这样
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;
}
上面假设高度是 int
field 。如果是 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
你可以用 the toMap
collector 来做到这一点.
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
创建一个流将其收集到 map 实现中,其中 Person::getHeight
是提取 map 键的人物高度的函数,Function.identity()
是一个为 map 值提取人物对象的函数,(left, right) -> left)
称为合并函数,意味着如果两个给定的人具有相同的键(高度),我们将返回第一个人( left
)。相反,(left, right) -> right
如果发生 key 冲突,将返回最后一个人。
最后,我们将处理结果传递给HashSet
构造函数来创建 Set<Person>
.
关于java - 从 Java 中的集合对象列表中获取唯一项,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49887273/