【问题标题】:How can I map stream with grouping?如何使用分组映射流?
【发布时间】:2018-06-17 04:10:10
【问题描述】:

我有一个很长的孩子流。

// ordered by parent.id / child.id
Stream<Child> childStream;

说,

Child(id = 1, parent(id = 1))
Child(id = 2, parent(id = 1))
Child(id = 3, parent(id = 2))
Child(id = 4, parent(id = 2))
Child(id = 5, parent(id = 3))

每个Child 都有一个父级。

class Child {
    Parent parent;
}

现在,如何将流映射到Family 的流?

class Family {
    Parent parent;
    List<Child> children;
}

我已经知道Collectors.groupingBy,但是流太长了,无法将它们全部收集到Map 中。

【问题讨论】:

  • @YCF_L 如果Map&lt;Parent, List&lt;Child&gt;&gt; 只包含一个条目,没关系。流这么大。
  • 这个流是从哪里来的?定义“很长”。
  • 您必须处理Stream 的所有Child 实例才能构造Family 实例。即使你只想获取Stream&lt;Family&gt;中的第一个Family,也无法避免处理整个Stream&lt;Child&gt;。
  • Parent 和 Child 类型是什么?在我看来就像一棵树。这将需要在groupingBy 或自定义收集器之后进行一些后处理。此外,是否保证输入列表按照您的示例进行排序(广度优先)?否则,就没有办法懒惰地分组,因为在列表的最后可能有第一个孩子的孩子。
  • @JBNizet 查询来自事件日志表。长度取决于输入循环,但除缩减之外的任何终端节都不适用。

标签: java mapping java-stream


【解决方案1】:

为了将您的Child 实例分组为Family 实例,您必须处理Stream,因此需要终端操作。您可以使用groupingBy,然后将生成的Map 转换为您需要的Stream:

Stream<Family> families = 
    childStream.collect(Collectors.groupingBy(Child::getParent))
               .entrySet()
               .stream()
               .map(entry -> new Family(entry.getKey(),entry.getValue()));

这是假设您的 Family 类有一个 Family(Parent parent, List&lt;Child&gt; children) 构造函数。

【讨论】:

  • 为此,Parent 必须实现 equals(),并且可能是 hashCode()
  • @TomDrake 这是真的。
  • @Eran 原始流很长。 groupingBy 关心这个吗?
  • @JinKwon 很长有多长? “小心这个”是什么意思?
【解决方案2】:

这是StreamEx 的解决方案,如果流是按父(id)排序的。

StreamEx.of(childStream)
        .collapse((a, b) -> a.getParent().getId() == b.getParent().getId(), Collectors.toList())
        .map(cl-> new Family(cl.get(0).getParent(), cl))...;

collapse 是比较 groupBy 的惰性评估。例如,如果您只想获取前 5 个家庭,则只会加载前 5 个家庭中的孩子,而不是全部。

StreamEx.of(childStream)
        .collapse((a, b) -> a.getParent().getId() == b.getParent().getId(), Collectors.toList())
        .map(cl-> new Family(cl.get(0).getParent(), cl))
        .limit(5);

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-05-23
    • 1970-01-01
    • 2022-11-01
    • 1970-01-01
    • 1970-01-01
    • 2021-08-16
    相关资源
    最近更新 更多