【问题标题】:Java 8 Streams - Map Multiple Object of same type to a list using streamsJava 8 Streams - 使用流将多个相同类型的对象映射到列表
【发布时间】:2017-06-01 08:41:51
【问题描述】:

是否可以以更好的方式使用流来执行以下提到的步骤?

Set<Long> memberIds = new HashSet<>();
marksDistribution.parallelStream().forEach(marksDistribution -> {
        memberIds.add(marksDistribution.getStudentId());
        memberIds.add(marksDistribution.getTeacherId());
      });

instanceDistribution.getStudentId()instanceDistribution.getTeacherId() 都是 Long 类型。

可能会问这种问题,但我无法理解。简单来说是或否。如果是/否,那么如何和位解释。 如果可能的话,请讨论效率。

【问题讨论】:

    标签: java collections lambda java-8 java-stream


    【解决方案1】:

    是的,您可以使用flatMapStream 的单个元素映射为多个元素的Stream,然后将它们展平为单个Stream

    Set<Long> memberIds = 
        marksDistribution.stream()
                         .flatMap (marksDistribution -> Stream.of(marksDistribution.getStudentId(), marksDistribution.getTeacherId()))
                         .collect(Collectors.toSet());
    

    【讨论】:

    • 你能讨论一下与我所做的相比的效率吗?
    • @Eran 1+ 来自我,如果你有 jdk-9,你仍然可以使用 flatMapping 收集器:list.stream().collect(Collectors.flatMapping((MarksDistribution md) -> Stream.of (md.getStudentId(), md.getTeacherId()), Collectors.toSet()));
    • @Eugene Nice,我应该很快尝试一下 jdk-9。
    • @Eugene:与所有 Stream 操作一样,我只会在必要时使用 Collector 对应项。您可以将几乎每个 Stream 操作都表示为仅收集器的操作,尤其是在 Java 9 中,但它会安静难以阅读……
    【解决方案2】:

    您可以使用 3-args 版本的 collect:

    Set<Long> memberIds = 
        marksDistribution.parallelStream()
                         .collect(HashSet::new, 
                                  (s, m) -> {
                                       s.add(m.getStudentId());
                                       s.add(m.getTeacherId());
                                   }, Set::addAll);
    

    您当前的版本可能会产生错误的结果,因为您在非线程安全集合中并行添加元素。因此,您可能在集合中有多次相同的值。

    【讨论】:

    • 你能讨论一下与我所做的相比的效率吗?
    • @balboa_21 问题是你所做的有缺陷。在考虑效率之前,您应该考虑正确性。也就是说,使用 collect 是使用流获取所需内容的规范方式。
    • c:感谢您的快速回复。好吧,如果按理说,我没有使用 parallelStream() ?。
    • @balboa_21 仍然使用collect。否则,如果有人决定将来将 .stream() 更改为 .parallelStream(),您将留下一段代码将无法工作。
    • @balboa_21:如果您不使用并行操作,您可以直接在 Collection 上使用forEach,即根本不需要 Stream 操作。
    猜你喜欢
    • 2018-08-24
    • 2018-12-22
    • 2019-01-19
    • 2015-04-15
    • 1970-01-01
    • 2020-12-14
    • 1970-01-01
    • 2021-10-12
    • 1970-01-01
    相关资源
    最近更新 更多