根据条件从List <Object>中删除重复项

Lee*_*Way 5 java list set java-8

初始点:

public class Employee {
    private String id;
    private String name;
    private String age;
}
Run Code Online (Sandbox Code Playgroud)

我有一份员工名单: List<Employee> employee;

列表中的员工示例:

{id="1", name="John", age=10}
{id="2", name="Ana", age=12}
{id="3", name="John", age=23}
{id="4", name="John", age=14}
Run Code Online (Sandbox Code Playgroud)

我们假设这age是唯一的.

如何根据name属性从列表中删除所有重复项并在输出中保留最大的条目age

输出应如下所示:

{id="2", name="Ana", age=12}
{id="3", name="John", age=23}
Run Code Online (Sandbox Code Playgroud)

我尝试的方式:

HashSet<Object> temp = new HashSet<>();
employee.removeIf(e->!temp.add(e.getName()));
Run Code Online (Sandbox Code Playgroud)

..但这样第一场比赛将被保留 employee

{id="1", name="John", age=10}
{id="2", name="Ana", age=12}
Run Code Online (Sandbox Code Playgroud)

......我不知道如何在这里设置另一个条件以保持最大的条件age.

ern*_*t_k 5

这是一种name通过选择具有max的元素来对元素进行分组并减少组的方法age:

List<Employee> uniqueEmployees = employees.stream()
            .collect(Collectors.groupingBy(Employee::getName,
                    Collectors.maxBy(Comparator.comparing(Employee::getAge))))
        .values()
        .stream()
        .map(Optional::get)
        .collect(Collectors.toList());
Run Code Online (Sandbox Code Playgroud)

哪个[[id=2, name=Ana, age=12], [id=3, name=John, age=23]]与您的测试数据一起返回.


Fed*_*ner 5

除了已接受的答案之外,这里还有两种变体:

Collection<Employee> employeesWithMaxAge = employees.stream()
    .collect(Collectors.toMap(
             Employee::getName,
             Function.identity(),
             BinaryOperator.maxBy(Comparator.comparing(Employee::getAge))))
    .values();
Run Code Online (Sandbox Code Playgroud)

该方法用于Collectors.toMap按名称对员工进行分组,并以Employee实例作为值。如果存在同名员工,则第三个参数(二元运算符)选择具有最大年龄的员工。

另一个变体执行相同的操作,但不使用流:

Map<String, Employee> map = new LinkedHashMap<>(); // preserves insertion order
employees.forEach(e -> map.merge(
        e.getName(), 
        e, 
        (e1, e2) -> e1.getAge() > e2.getAge() ? e1 : e2));
Run Code Online (Sandbox Code Playgroud)

或者,与BinaryOperator.maxBy

Map<String, Employee> map = new LinkedHashMap<>(); // preserves insertion order
employees.forEach(e -> map.merge(
        e.getName(), 
        e, 
        BinaryOperator.maxBy(Comparator.comparing(Employee::getAge))));
Run Code Online (Sandbox Code Playgroud)