简体   繁体   English

使用 java8 (Streams) 的自定义对象比较列表

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

I have two Lists containing objects of this class:我有两个包含此类对象的列表:

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

I want to compare the objects in those two lists by students.我想由学生比较这两个列表中的对象。 I have to compare the lists and get data lijke below我必须比较列表并获得下面的数据

  1. I need to create a new List containing those ClassObj objects which are present in list1 but not in list2我需要创建一个新列表,其中包含那些存在于list1但不在list2 ClassObj对象
  2. I need to create a new List containing those ClassObj objects which are present in list2 but not in list1我需要创建一个新列表,其中包含那些存在于list2但不在list1 ClassObj对象
  3. I need to create a new List containing those ClassObj objects which are present in both the lists using java8 streams我需要创建一个新列表,其中包含使用 java8 流出现在两个列表中的ClassObj对象

I tried with the below code我尝试使用以下代码

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

To find students who got TC (exists in list 1 but not in list2)查找获得 TC 的学生(存在于列表 1 但不在列表 2 中)

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

To find new Admission (exists in list2 but not in list1)寻找新的准入(存在于列表 2 但不在列表 1 中)

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

To find Students continuing in the school (exists in both list)查找继续留在学校的学生(存在于两个列表中)

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());

It is returning me the results properly but i dont want to go through two streams and filter data, how to optimize the above code efficiently.它正确地返回了我的结果,但我不想通过两个流和过滤数据,如何有效地优化上面的代码。 ie, by using single stream即,通过使用单流

You might not really need Stream s at all for the task.您可能根本不需要Stream来完成任务。 How about this -这个怎么样 -

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);

For part 3 Common elements from both the List对于列表中的第 3 部分公共元素

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

After that, you can change the Set into a List.之后,您可以将 Set 更改为 List。

For Part 1 And 2, you need to override the equals and hashcode method in ClassObj.对于第 1 部分和第 2 部分,您需要覆盖 ClassObj 中的 equals 和 hashcode 方法。 So, you can use contains methods of the list.因此,您可以使用包含列表的方法。 ArrayList's custom Contains method 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