根据Java 8中的属性从对象列表中删除重复项 [英] Remove duplicates from a list of objects based on property in Java 8
问题描述
我正在尝试根据某些属性从对象列表中删除重复项。
I am trying to remove duplicates from a List of objects based on some property.
我们可以使用java 8以简单的方式完成吗
can we do it in a simple way using java 8
List<Employee> employee
我们可以根据 id $ c $从中删除重复项c>员工的财产。我见过帖子从字符串的arraylist中删除重复的字符串。
Can we remove duplicates from it based on id
property of employee. I have seen posts removing duplicate strings form arraylist of string.
推荐答案
你可以从获取一个流列出
并输入 TreeSet
,从中提供一个唯一比较id的自定义比较器。
You can get a stream from the List
and put in in the TreeSet
from which you provide a custom comparator that compares id uniquely.
然后,如果你真的需要一个列表,你可以把这个集合放回一个ArrayList。
Then if you really need a list you can put then back this collection into an ArrayList.
import static java.util.Comparator.comparingInt;
import static java.util.stream.Collectors.collectingAndThen;
import static java.util.stream.Collectors.toCollection;
...
List<Employee> unique = employee.stream()
.collect(collectingAndThen(toCollection(() -> new TreeSet<>(comparingInt(Employee::getId))),
ArrayList::new));
给出示例:
List<Employee> employee = Arrays.asList(new Employee(1, "John"), new Employee(1, "Bob"), new Employee(2, "Alice"));
它将输出:
[Employee{id=1, name='John'}, Employee{id=2, name='Alice'}]
另一个想法可能是使用包装员工的包装器,并使用基于其id的equals和hashcode方法: / p>
Another idea could be to use a wrapper that wraps an employee and have the equals and hashcode method based with its id:
class WrapperEmployee {
private Employee e;
public WrapperEmployee(Employee e) {
this.e = e;
}
public Employee unwrap() {
return this.e;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
WrapperEmployee that = (WrapperEmployee) o;
return Objects.equals(e.getId(), that.e.getId());
}
@Override
public int hashCode() {
return Objects.hash(e.getId());
}
}
然后你包装每个实例,调用 distinct()
,打开它们并将结果收集到列表中。
Then you wrap each instance, call distinct()
, unwrap them and collect the result in a list.
List<Employee> unique = employee.stream()
.map(WrapperEmployee::new)
.distinct()
.map(WrapperEmployee::unwrap)
.collect(Collectors.toList());
事实上,我认为你可以做到这一点通过提供将进行比较的函数来包装泛型:
In fact, I think you can make this wrapper generic by providing a function that will do the comparison:
class Wrapper<T, U> {
private T t;
private Function<T, U> equalityFunction;
public Wrapper(T t, Function<T, U> equalityFunction) {
this.t = t;
this.equalityFunction = equalityFunction;
}
public T unwrap() {
return this.t;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
@SuppressWarnings("unchecked")
Wrapper<T, U> that = (Wrapper<T, U>) o;
return Objects.equals(equalityFunction.apply(this.t), that.equalityFunction.apply(that.t));
}
@Override
public int hashCode() {
return Objects.hash(equalityFunction.apply(this.t));
}
}
,映射将为:
.map(e -> new Wrapper<>(e, Employee::getId))
这篇关于根据Java 8中的属性从对象列表中删除重复项的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!