试图从基于某些属性的对象列表中删除重复项。
我们可以使用Java 8以简单的方式做到吗
List<Employee> employee
我们可以根据id员工的财产从中删除重复项吗?我看到过从字符串arraylist中删除重复字符串的帖子。
id
你可以从获取流List并将其放入TreeSet其中,从中提供一个唯一比较ID的自定义比较器。
List
TreeSet
然后,如果你确实需要一个列表,则可以将该集合放回到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方法:
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(),解开它们并将结果收集在列表中。
distinct()
List<Employee> unique = employee.stream() .map(WrapperEmployee::new) .distinct() .map(WrapperEmployee::unwrap) .collect(Collectors.toList());
实际上,我认为你可以通过提供进行比较的函数来使此包装器通用:
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))