基于属性和谓词在Java 8中删除重复项

5

根据https://dev59.com/tV0b5IYBdhLWcg3wC9aJ#29671501的问题:

给定一个包含员工ID、姓名和智商的列表:

List<Employee> employee = Arrays.asList(new Employee(1, "John", 80), new Employee(1, "Bob", 120), Employee(1, "Roy", 60), new Employee(2, "Alice", 100));

我想要输出:
[Employee{id=1, name='Bob', iq=120}, Employee{id=2, name='Alice', iq=100}]

因此,根据员工的id属性从列表中删除重复项,并选择智商最高的员工,这是显而易见的原因。:)

特别是,我对调整仅基于id删除重复项的解决方案感兴趣:

    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));

有没有办法?

5
List<Employee> unique = employee.stream().collect(collectingAndThen(toMap(Employee::getId, Function.identity(), BinaryOperator.maxBy(Comparator.comparingInt(Employee::getIq))), m -> new ArrayList<>(m.values())));这行代码的作用是从一个名为employee的员工列表中筛选出具有唯一ID的员工,并按照智商(属性为iq)从大到小排序。最终,将筛选出的结果以List<Employee>的形式保存在unique变量中。 - Holger
1个回答

7

那么,这样怎么样呢?

Collection<Employee> distinctEmps = employee.stream()
    .collect(Collectors.toMap(Employee::getId, Function.identity(), 
        (e1, e2) -> e1.getIq() >= e2.getIq() ? e1 : e2))
    .values();

仅仅遵循 @Holgers 的方法,另外一个变体是:
Collection<Employee> distinctEmps = employee.stream()
    .collect(Collectors.toMap(Employee::getId, Function.identity(), 
        BinaryOperator.maxBy(Comparator.comparing(Employee::getIq))))
    .values();

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接