java 8 lambda - 多次使用流

标签 java lambda

是否可以避免在同一个集合中的当前流内创建流,如下面的示例中收集一些数据(使用 listOfA 两次来创建流)?

List<A> listOfA = Arrays.asList(new A(1L, "A1", "V1"), new A(2L, "A2", "V1"), new A(1L, "A1", "V2"));

List<B> listOfB = listOfA.stream().map(r -> new B(r.getId(), r.getName(),
            listOfA.stream().filter(r2 -> r.getId().equals(r2.getId())).map(A::getVal).collect(toSet())
    )).distinct().collect(toList());

class A {
     private final Long id;
     private final String name;
     private final String val;

     A(Long id, String name, String val) //constructor
     //getters

}

class B {
     private final Long id;
     private final String name;
     private final Set<String> values;

     B(Long id, String name, Set<String> values) //constructor
     //getters


     @Override
     public boolean equals(Object o) {
          ...
          return id.equals(a.id);
     }
     //hashCode
 }

最终结果应该是 2 个对象的列表:

B{id=1, name='A1', 值=[V1, V2]}

B{id=2,名称='A2',值=[V1]

提前致谢!

最佳答案

不知道你问这个问题的目的是什么。如果问题是为了避免重新创建流而需要进行的最小更改是什么,那么我必须回答:我不知道。但是,您的方法似乎过于复杂。外链map , collect , filter , distinctcollect在那里 build 的东西真的很难理解。

简短的咆哮之后......

也许我担心 future 的 Java 程序都会像这样,从而变得完全不可维护,这是没有道理的。也许人们只是“习惯”这种编程风格。也许有一个短暂的时期,当人们过于渴望使用新的语言功能时,它迟早会回到“正常”风格(以及功能元素的“健康”水平)。但我个人认为像 createBsByMergingTheValuesOfAs() 这样的方法在这里就足够并且合适了。

...我建议使用专用的Collector ,它已经提供了许多用于可变减少的基础设施,您似乎正在通过此操作链来模拟:

import java.util.Arrays;
import java.util.Collections;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;

public class StreamCollectTest
{
    public static void main(String[] args)
    {
        List<A> listOfA = Arrays.asList(
            new A(1L, "A1", "V1"), 
            new A(2L, "A2", "V1"), 
            new A(1L, "A1", "V2"));

        Map<Long, B> result = listOfA.stream().collect(
            Collectors.toConcurrentMap(

                // The "id" will be the key of the map
                a -> a.getId(), 

                // The initial value stored for each key will be a "B"
                // whose set of values contains only the element of 
                // the corresponding "A"
                a -> new B(a.getId(), a.getName(), 
                    new LinkedHashSet<String>(Collections.singleton(a.getVal()))),

                // Two "B"s with the same key will be merged by adding
                // all values from the second "B" to that of the first
                (b0,b1) -> { b0.values.addAll(b1.values); return b0; }));

        System.out.println(result);
    }

    static class A
    {
        private final Long id;
        private final String name;
        private final String val;

        A(Long id, String name, String val)
        {
            this.id = id;
            this.name = name;
            this.val = val;
        }

        public Long getId()
        {
            return id;
        }

        public String getName()
        {
            return name;
        }

        public String getVal()
        {
            return val;
        }
    }

    static class B
    {
        private final Long id;
        private final String name;
        private final Set<String> values;

        B(Long id, String name, Set<String> values)
        {
            this.id = id;
            this.name = name;
            this.values = values;
        }

        @Override
        public String toString()
        {
            return id+","+name+","+values;
        }
    }
}

打印

{1=1,A1,[V1, V2], 2=2,A2,[V1]}

所以values()生成的 map 应该正是您正在寻找的内容。

关于java 8 lambda - 多次使用流,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24490033/

相关文章:

java - 如何在框架中查找组件

java - 如何在循环内另外迭代 for(String s : st) in java?

C++ 在 lambda 函数中使用此指针和绑定(bind)

lambda - 在 Scheme 中消除 lambda?

c# - VS2015 即时窗口中的 lambda 表达式

c# - 在 C# 中的数据模型上运行 lambda 时不支持的异常

java - 多线程 JMX 客户端

java - 以线程安全的方式缓存preparestatement?

java - 破解 : Duplicates in java. util.TreeSet?

python - 如何使用理解列表创建包含 lambda 表达式的字典?