Список пользовательских объектов сравнения с использованием java8 (Streams) - PullRequest
4 голосов
/ 30 января 2020

У меня есть два списка, содержащие объекты этого класса:

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

Я хочу сравнить объекты в этих двух списках по студентам. Я должен сравнить списки и получить данные ниже

  1. Мне нужно создать новый список, содержащий те ClassObj объекты, которые присутствуют в list1, но не в list2
  2. Мне нужно создать новый список, содержащий те ClassObj объекты, которые присутствуют в list2, но отсутствуют в list1
  3. Мне нужно создать новый список, содержащий те ClassObj объекты, которые присутствуют в обоих списках используя потоки java8

Я пытался с помощью приведенного ниже кода

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

Найти студентов, которые получили T C (существует в списке 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());

Он возвращает мне результаты правильно, но я не хочу go через два потока и фильтровать данные, как эффективно оптимизировать приведенный выше код. то есть, используя один поток

Ответы [ 2 ]

2 голосов
/ 30 января 2020

Возможно, вам не понадобятся 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);
1 голос
/ 30 января 2020

Для части 3 Общие элементы из Списка

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

После этого вы можете изменить Набор в Список.

Для Частей 1 и 2 вам необходимо переопределить равно и метод хэш-кода в ClassObj. Итак, вы можете использовать содержащиеся в списке методы. Пользовательский метод ArrayList Contains

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