首页 > 解决方案 > 基于 Java 8 中的属性和谓词删除重复项

问题描述

基于https://stackoverflow.com/a/29671501/2517622的问题

给定具有 id、name 和 IQ 的员工列表:

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

有办法吗?

标签: javajava-8

解决方案


这个怎么样,

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

推荐阅读