Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java 8 Nested stream find minimum

I have a data structure like this:

class Parent {
  List<Child> children;
}
class Child {
  DateTime date;
}

List<Parent> parents = ...

I want to find the earliest Child DateTime in all the parents

I want one result. The earliest DateTime across all the parents and all their children.

List<Parent> parents = create();

List<Child> epp = new ArrayList<Child>();//earliest per parent

parents.forEach(c -> c.getChildren()
                      .stream()
                      .min(Comparator.comparing(Child::getDate))
                      .ifPresent(d -> epp.add(d)));

Optional<Child> earliest = epp.stream()
                              .min(Comparator.comparing(Child::getDate));

Loop each parent, add the earliest per parent into the epp list, and then I loop the epp list to find the actual earliest.

Is this the most concise / best way to achieve with Java8?

like image 254
kwh Avatar asked Mar 04 '26 16:03

kwh


1 Answers

Yes there is. You don't need to use the intermediate list if you flatten the map to children:

Optional<Child> earliest = parents.stream().
    .map(Parent::getChildren).flatMap(List::stream)
    .min(Comparator.comparing(Child::getDate));

If you are able to change the Parent class then you might want to add a streamChildren method in Parent:

class Parent {
    public Stream<Child> streamChildren() {
        return children.stream();
    }
}

This has the advantage of not giving the caller access to the underlying List.

As an aside, you didn't need to create your own ArrayList in the original solution. You could have used:

List<Child> earliest = parents.stream().map(Parent::getChildren)
    .map(children -> children.stream().min(Comparator(Child::getDate)))
    .filter(Optional::isPresent).map(Optional::get).distinct()
    .collect(Collectors.toList());

That avoids the side effect of the 'add' operation.

like image 144
sprinter Avatar answered Mar 07 '26 06:03

sprinter



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!