繁体   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