java 8 lambda - 多次使用流

时间:2014-06-30 12:20:00

标签: 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',values = [V1,V2]}

B {id = 2,name ='A2',values = [V1]

提前致谢!

1 个答案:

答案 0 :(得分:0)

我不确定你的问题是针对什么的。如果问题是为了避免重新创建流而需要的最小变化是什么,那么我必须回答:我不知道。但是,您的方法似乎过于复杂。在那里构建的mapcollectfilterdistinctcollect链很难理解。

短暂的咆哮......

  

也许我担心未来的Java程序看起来都像这样,因此变得完全无法维护是不合理的。也许一个人已经习惯了#34;这种编程风格。也许在人们过于渴望使用新语言功能的短暂时期内,它会回到正常状态。风格(以及&#34;健康&#34;功能元素的水平)迟早。但我个人认为像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()应该正是您要查找的内容。