0

I have a list that reads like

List<Student> students = Arrays.asList(
    new Student("1234", "steve", LocalDate.parse("2019-09-01"),  LocalDate.parse("2019-09-10")), 
    new Student("1234", "steve", LocalDate.parse("2019-09-11"),  LocalDate.parse("2019-09-20")),
    new Student("1234", "George", LocalDate.parse("2019-09-01"),  LocalDate.parse("2019-09-10")));

The domain model of student holds four values Students = {String class_num, String name, LocalDate startDate, LocalDate endDate}

I am trying to group by the attribute name and get min(startDate) and max(endDate) for distinct names found in the list.

The expected result for the above input should be

{{"1234", "steve", 2019-09-01, 2019-09-20},
{"1234", "George", 2019-09-01, 2019-09-10}}

//took the min of date for steve and max of date for steve

Can this be achieved through the use of stream api in java?

1 Answers1

0

Your problem of finding minimum and maximum has to be in two separate operations. Therefore, we need to stream twice in order to find out those results.

public static void main(String[] args)
    {
        List<Student> students = Arrays.asList(
                new Student("1234", "steve", LocalDate.parse("2019-09-01"),  LocalDate.parse("2019-09-10")),
                new Student("1234", "steve", LocalDate.parse("2019-09-11"),  LocalDate.parse("2019-09-20")),
                new Student("4321", "George", LocalDate.parse("2019-09-01"),  LocalDate.parse("2019-09-10")));

        Map<String, List<String>> result = new HashMap<>();

        Map<String, List<Student>> collect = students.stream()
                .collect(Collectors.groupingBy(Student::getName));

        // finding the minimum start date
        collect.values().forEach(list -> list.stream()
                .min(Comparator.comparing(Student::getStartDate))
                .ifPresent(s -> handleResult(result, s.getId(), s.getName(), s.getStartDate())));
        // finding the maximum end date
        collect.values().forEach(list -> list.stream()
                .max(Comparator.comparing(Student::getEndDate))
                .ifPresent(s -> handleResult(result, s.getId(), s.getName(), s.getEndDate())));
        System.out.println(result);
    }

    private static void handleResult(Map<String, List<String>> result, String id, String name, LocalDate date) {
        if (result.containsKey(id)){
            List<String> strings = result.get(id);
            strings.add(date.toString());
        }else {
            ArrayList<String> strings = new ArrayList<>();
            strings.add(id);
            strings.add(name);
            strings.add(date.toString());

            result.put(id, strings);
        }
    }

Output

{1234=[1234, steve, 2019-09-01, 2019-09-20], 4321=[4321, George, 2019-09-01, 2019-09-10]}
Jude Niroshan
  • 4,280
  • 8
  • 40
  • 62