简体   繁体   English

从Java中的arraylist获取唯一对象的列表

[英]get list of unique objects from an arraylist in java

I have a list of employees as follows: 我有以下员工名单:

[Employee{id="1", NID="A123", wages=5000},
 Employee{id="2", NID="B123", wages=1000},
 Employee{id="3", NID="C123", wages=2000},
 Employee{id="4", NID="C123", wages=3000}]

I need to be able to retrieve only the unique objects and where NID is the same, I need to retrieve the one with the max Id. 我需要能够仅检索唯一的对象,并且在NID相同的地方,我需要检索具有最大ID的对象。 So the final list should be like 所以最终清单应该像

[Employee{id="1", NID="A123", wages=5000},
 Employee{id="2", NID="B123", wages=1000},
 Employee{id="4", NID="C123", wages=3000}]

I know it is possible to do it with nested for loops but I want to do it with Java streams. 我知道可以使用嵌套的for循环来做到这一点,但是我想使用Java流来做到这一点。 I could find which employee are duplicate in the list by using the group by but I still can't figure how to get the list like above. 通过使用分组依据,我可以找到列表中重复的员工,但是我仍然不知道如何获取上面的列表。

 Map<String, List<Employee>> groupByNid = employeeList.stream().collect(Collectors.groupingBy(Employee::getNID));

Thanks to help. 感谢帮助。

Ashley 阿什利

I propose the following: 我提出以下建议:

    Collection<Employee> filteredEmployees = employeeList.stream()
            .collect(Collectors.toMap(
                    Employee::getNID, Function.identity(),
                    BinaryOperator.maxBy(Comparator.comparing(Employee::getID))
            )).values();

You can collect to map, using the NID field for keys, and then selecting the highest ID field in the merge function: 您可以使用NID字段作为键,然后在合并功能中选择最高的ID字段来收集地图:

List<Employee> employeeList = ...;
Collection<Employee> uniqueEmployees = employeeList.stream()
        .collect(Collectors.toMap(Employee::getNID, 
                Function.identity(), 
                (e1,e2) -> e1.getID().compareTo(e2.getID()) > 0 ? e1: e2)
        ).values();

You can do it like so, 你可以这样做

Collection<Employee> emps = employees.stream()
        .collect(Collectors.collectingAndThen(Collectors.toMap(Employee::getNID, Function.identity(),
                (e1, e2) -> e1.getId().compareTo(e2.getId()) > 0 ? e1 : e2), m -> m.values()));

Try This: 尝试这个:

    List<Employee> list = new ArrayList<>();

    list.add(new Employee(1,"A123",5000));
    list.add(new Employee(2,"B123",1000));
    list.add(new Employee(3,"C123",2000));
    list.add(new Employee(4,"C123",2000));


    Set<String> empSet = new HashSet<>();
    list.removeIf(p -> !empSet.add(p.getNid()));
    list.forEach(emp->System.out.println(emp.getId() +" : "+emp.getNid()+" :"+emp.getWage()));

You can do it like: 您可以这样做:

employeeList.stream().collect(Collectors.toMap(
        Employee::getNID, r -> r, (e1, e2) ->  e1.getId().compareTo(e2.getId()) > 0 ? e1 : e2));
@Test
public void t() {
    Employee e1 = new Employee(1, "A123", 400);
    Employee e2 = new Employee(2, "A123", 400);

    List<Employee> list = Arrays.asList(e1,e2);

    list = list.stream().filter(distinctByNid(Employee::getNid)).collect(Collectors.toList());
    System.out.println(list);
}

// use a thread safe set to dedup
public static <T> Predicate<T> distinctByNid(Function<? super T, ?> keyExtractor) {
    Set<Object> seen = ConcurrentHashMap.newKeySet();
    return t -> seen.add(keyExtractor.apply(t));
}

static class Employee {
    private int id;
    private String nid;
    private int wages;

    public Employee(int id, String nid, int wages) {
        this.id = id;
        this.nid = nid;
        this.wages = wages;
    }

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getNid() {
        return nid;
    }

    public void setNid(String nid) {
        this.nid = nid;
    }

    public int getWages() {
        return wages;
    }

    public void setWages(int wages) {
        this.wages = wages;
    }

    @Override
    public String toString() {
        return "Employee{" +
                "id=" + id +
                ", nid='" + nid + '\'' +
                ", wages=" + wages +
                '}';
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM