在类和子类中使用流的最佳方法

时间:2018-10-15 18:56:24

标签: lambda java-8 java-stream

我在Java 8中使用流时遇到问题,我有3个这样的类:

public Class A {
    String string1A;
    String string2A;
    List<B> listB;
    .
    .
    .
}
public Class B {
    String string1B;
    String string2B;
    .
    .
    .
}
public Class C {
    String string1A;
    String string2A;
    String string1B;
    String string2B;
    .
    .
    .
}

然后,我有一个方法返回一个C的列表,其中所有数据都来自数据库,并且我需要创建一个将所有数据分组的列表A,分组值为String1A。我的想法是这样的:

List<A> listA = new ArrayList<A>();

    Set<String> listString1A = listC.stream().map(x->x.getString1A()).distinct().collect(Collectors.toSet());

for(String stringFilter1A: listString1A){
    A a = listC.stream()
               .filter(x->getString1A().equals(stringFilter1A))
               .map(x-> new A(x.getString1A(),x.getString2A))
               .findFirst().get();
    List<B> listB = listC.stream()
                         .filter(x->getString1A().equals(stringFilter1A))
                         .map(x-> new B(...))
                         .collect(Collectors.toList());
    a.setListB(listaB);
    listaA.add(a);
}

是否可以仅使用流或尝试删除for进行此类查询?

谢谢。

1 个答案:

答案 0 :(得分:1)

这是一种将c元素按A分组的方式,将每个C映射到新的B

Map<A, List<B>> map = listC.stream()
    .collect(Collectors.groupingBy(
        c -> new A(...),     // construct new A instance out from c instance
        Collectors.mapping(
            c -> new B(...), // construct new B instance out from c instance
            Collectors.toList())));

这需要类A基于hashCode一致地实现equalsstring1A

然后,您只需为地图中的每个List<B>设置A

map.forEach((a, listB) -> a.setListB(listB));

地图键就是您想要的:

Set<A> setA = map.keySet();

或者如果您确实需要列表:

List<A> listA = new ArrayList<>(map.keySet());