Java 8嵌套流找到最小值

时间:2015-10-11 23:04:14

标签: java lambda java-8 java-stream

我有这样的数据结构:

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

List<Parent> parents = ...

我想找到所有Child

中最早的parents日期时间

我想要一个结果。所有DateTime及其所有parents中的最早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));

循环每个父项,将每个父项最早添加到epp列表中,然后循环epp列表以找到最早的父项。

这是使用Java8实现最简洁/最好的方法吗?

1 个答案:

答案 0 :(得分:3)

是的。如果将地图展平为儿童,则无需使用中间列表:

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

如果您能够更改Parent类,那么您可能希望在Parent中添加streamChildren方法:

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

这样做的好处是不会让调用者访问基础List

顺便说一句,您不需要在原始解决方案中创建自己的ArrayList。您可以使用:

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

这避免了'添加'操作的副作用。