簡體   English   中英

使用 java8 (Streams) 的自定義對象比較列表

[英]List of custom object comparison using java8 (Streams)

我有兩個包含此類對象的列表:

public class ClassObj {
    private Integer Id;
    private List<String> students;
}

我想由學生比較這兩個列表中的對象。 我必須比較列表並獲得下面的數據

  1. 我需要創建一個新列表,其中包含那些存在於list1但不在list2 ClassObj對象
  2. 我需要創建一個新列表,其中包含那些存在於list2但不在list1 ClassObj對象
  3. 我需要創建一個新列表,其中包含使用 java8 流出現在兩個列表中的ClassObj對象

我嘗試使用以下代碼

List<ClassObj> prevYearList = getPrevYearData(id);
List<ClassObj> currYearList = getCurrentYearData(id);

查找獲得 TC 的學生(存在於列表 1 但不在列表 2 中)

List<ClassObj> studentsGotTC = prevYearList.stream()
                    .filter(curr -> (currYearList.stream().filter(prev -> prev.getStudents().equals(curr.getStudents()))
                            .count()) < 1)
                    .collect(Collectors.toList());

尋找新的准入(存在於列表 2 但不在列表 1 中)

List<ClassObj> newAdmission = currYearList.stream()
                    .filter(prev -> (prevYearList.stream()
                            .filter(curr -> prev.getStudents().equals(curr.getStudents())).count()) < 1)
                    .collect(Collectors.toList());

查找繼續留在學校的學生(存在於兩個列表中)

List<List<String>> studentsList = studentsGotTC.parallelStream()
                    .map(ClassObj::getStudents)
                    .collect(Collectors.toList());
List<ClassObj> existingStudents = prevYearList.stream()
                    .filter(e -> !studentsList.contains(e.getStudents()))
                    .collect(Collectors.toList());

它正確地返回了我的結果,但我不想通過兩個流和過濾數據,如何有效地優化上面的代碼。 即,通過使用單流

您可能根本不需要Stream來完成任務。 這個怎么樣 -

Set<ClassObj> uniqueStudentsOfPrevYear = new HashSet<>(prevYearList);
Set<ClassObj> uniqueStudentsOfCurrYear = new HashSet<>(currYearList);

List<ClassObj> studentsWithTC = new ArrayList<>(prevYearList);
studentsWithTC.removeIf(uniqueStudentsOfCurrYear::contains);

List<ClassObj> newAdmissions = new ArrayList<>(currYearList);
newAdmissions.removeIf(uniqueStudentsOfPrevYear::contains);

List<ClassObj> overlapping = new ArrayList<>(currYearList);
overlapping.retainAll(uniqueStudentsOfPrevYear);

對於列表中的第 3 部分公共元素

Set<String> result = list.stream()
  .distinct()
  .filter(otherList::contains)
  .collect(Collectors.toSet());

之后,您可以將 Set 更改為 List。

對於第 1 部分和第 2 部分,您需要覆蓋 ClassObj 中的 equals 和 hashcode 方法。 因此,您可以使用包含列表的方法。 ArrayList 的自定義 Contains 方法

List<ClassObj> studentsGotTC = prevYearList.stream()
                    .filter(prevYear-> currList.contains(prevYear))
                    .collect(Collectors.toList());

暫無
暫無

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

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