簡體   English   中英

Java-Streams - filter() + map() - Map 來自一個列表的對象缺少屬性到另一個列表的對象

[英]Java-Streams - filter() + map() - Map objects from one List with the missing property to objects from another List

過濾列表后一個object到另一個object的Map屬性

我有兩個Student對象列表。

public class Student {
    private Integer id;
    private String name;
    private String status;

    // the rest code
}

我想從list2中獲取id不存在於list1中的學生。

Student s1 = new Student(1, "A", "active");
Student s2 = new Student(2, "B", "active");
Student s3 = new Student(3, "C", "active");

List<Student> list1 = new ArrayList<>();
list1.add(s1);
list1.add(s2);
list1.add(s3);

Student s4 = new Student(null, "A", "inactive");
Student s5 = new Student(null, "B", "inactive");
Student s6 = new Student(null, "E", "inactive");

List<Student> list2 = new ArrayList<>();
list2.add(s4);
list2.add(s5);
list2.add(s6);

這是我的解決方案:

final List<Student> list = list2.stream()
    .filter(p -> list1.stream().anyMatch(p2 -> p.getName() == p2.getName()))
    .collect(Collectors.toList());

當前結果:

[null - A - inactive, null - B - inactive]

我想在list1中的AB的 map id以便所需的結果是:

[1- A - inactive, 2 - B - inactive]

那么,如何在一行代碼(單流狀態)中執行這兩個操作filtermap

那么如何在一行代碼(單個流語句)中同時執行操作filtermap

這絕對是可行的,但是由於通過list1的冗余迭代,它的效率不會那么高(只需應用map並像使用filter一樣遍歷list1 ,這非常簡單,所以我要離開了如果他們對此感興趣,則將其作為練習供 OP 和讀者使用)。

這是如何在單個流語句中使用 Java 16 mapMulty()來完成的示例:

List<Student> result = list2.stream()
    .<Student>mapMulti((student, consumer) -> {
        if (student.getId() == null) {
            list1.stream().filter(s -> s.getName().equals(student.getName()))
                .findFirst()
                .ifPresent(consumer);
        }
    }).toList();

更高效的方法是索引list1中學生的所有idname s

要確定list1中存在哪個id (第一個屬性),我們可以生成一個HashSet ,它比一遍又一遍地遍歷list1要好得多。

並按namelist1中檢索學生(為了替換list2id等於null的學生),我們可以生成Map

旁注:如果您的目標是比較對象的屬性,而不是如果兩個引用都指向相同的 object,則不要使用身份比較==來比較對象。

這就是它的實現方式:

Set<Integer> studentIds = list1.stream()
    .map(Student::getId)
    .collect(Collectors.toSet());
        
Map<String, Student> studentById = list1.stream()
    .collect(Collectors.toMap(
        Student::getName,       // extracting a key
        Function.identity(),    // extracting a value
        (left, right) -> left   // resolving the students mapped to the same key (i.e. having the same name)
    ));
        
List<Student> result = list2.stream()
    .filter(student -> !studentIds.contains(student.getId()))      // ID doesn't exists in the list1
    .filter(student -> studentById.containsKey(student.getName())) // name is present in the list1
    .map(student -> studentById.get(student.getName()))            // replace student from the list2 with a namesake-student from the list1
    .collect(Collectors.toList());

result.forEach(System.out::println);

Output:

Student{id=1, name='A', status='active'}
Student{id=2, name='B', status='active'}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM