Lambda 单个流中的多个过滤器

Lambda 单个流中的多个过滤器,lambda,java-8,Lambda,Java 8,我已经使用Java8流编写了一段代码,但正在尝试重构 我用不同的标准筛选了列表,并将其存储到新列表中。是否有任何方法可以一次筛选所有条件并将结果组存储到列表中。我不知道该怎么解释 这是我的代码,只需要重构它 List<A> finalList = new ArrayList<>(); List<A> aList= new ArrayList<>(); A objectA = new A(); List<B> bList = new

我已经使用Java8流编写了一段代码,但正在尝试重构

我用不同的标准筛选了列表,并将其存储到新列表中。是否有任何方法可以一次筛选所有条件并将结果组存储到列表中。我不知道该怎么解释

这是我的代码,只需要重构它

List<A> finalList = new ArrayList<>();
List<A> aList= new ArrayList<>();

A objectA = new A();

List<B> bList = new ArrayList<>();
bList.add(new B(5700));
bList.add(new B(5750));
bList.add(new B(5800));
bList.add(new B(5812));
bList.add(new B(5803));
bList.add(new B(5802));

objectA.setMyList(bList);

aList.add(objectA);

aList.stream()
    .forEach(
        a -> {
            if(!a.getMyList.isEmpty()){
                List<B> groupA =
                    a.getMyList.stream()
                        .filter(b -> b.getType() == 5700 || b.getType() == 5750)
                        .collect(Collectors.toList());
                List<B> groupB =
                    a.getMyList.stream()
                        .filter(b -> b.getType() == 5800 || b.getType() == 5810)
                        .collect(Collectors.toList());
                List<B> groupC =
                    a.getMyList.stream()
                        .filter(b -> b.getType() == 5802 || b.getType() == 5812)
                        .collect(Collectors.toList());
                List<B> groupD =
                    a.getMyList.stream()
                        .filter(b -> b.getType() == 5803 || b.getType() == 5813)
                        .collect(Collectors.toList());



                if(!groupA.isEmpty()){
                    finalList.add(getAWithGroupList(a, groupA));
                }
                if(!groupB.isEmpty()){
                    finalList.add(getAWithGroupList(a, groupB));
                }
                if(!groupC.isEmpty()){
                    finalList.add(getAWithGroupList(a, groupC));
                }
                if(!groupD.isEmpty()){
                    finalList.add(getAWithGroupList(a, groupD));
                }
             }
        }
    );


private A getAWithGroupList(A a, List<B> group) {
    A a = (A) a.clone();
    a.setMyList(group);
    return a;
}
List finalList=new ArrayList();
列表列表=新的ArrayList();
A objectA=新的A();
List bList=new ArrayList();
添加(新B(5700));
bList.add(新B(5750));
添加(新B(5800));
bList.add(新B(5812));
添加(新B(5803));
添加(新B(5802));
objectA.setMyList(bList);
添加(objectA);
流()
弗雷奇先生(
a->{
如果(!a.getMyList.isEmpty()){
列表组A=
a、 getMyList.stream()
.filter(b->b.getType()==5700 | | b.getType()==5750)
.collect(Collectors.toList());
列表组B=
a、 getMyList.stream()
.filter(b->b.getType()==5800 | | b.getType()==5810)
.collect(Collectors.toList());
列表组C=
a、 getMyList.stream()
.filter(b->b.getType()==5802 | | b.getType()==5812)
.collect(Collectors.toList());
列表组D=
a、 getMyList.stream()
.filter(b->b.getType()==5803 | | b.getType()==5813)
.collect(Collectors.toList());
如果(!groupA.isEmpty()){
add(getAWithGroupList(a,groupA));
}
如果(!groupB.isEmpty()){
add(getAWithGroupList(a,groupB));
}
如果(!groupC.isEmpty()){
add(getAWithGroupList(a,groupC));
}
如果(!groupD.isEmpty()){
add(getAWithGroupList(a,groupD));
}
}
}
);
私有A getAWithGroupList(A,列表组){
A=(A)A.clone();
a、 setMyList(组);
返回a;
}
如有任何帮助或建议,将不胜感激


谢谢。

简单。将重复代码包装到方法中:

private List<B> listifyAndfilter(A a, Predicate<List<B>> check){
    return a.getMyList.stream().filter(check).collect(Collectors.toList());
}
对于每个循环,将其转换为:

for (List<B> group : new List<B>[]{groupA, groupB, groupC, groupD}) // Packs the lists in an array and iterates over the array
    if(!group.isEmpty())
        finalList.add(getAWithGroupList(a, group));
for(List group:new List[]{groupA,groupB,groupC,groupD})//将列表打包到数组中并在数组中迭代
如果(!group.isEmpty())
add(getAWithGroupList(a,group));

最大的障碍是您的标准背后的基本原理未知。所以当我们不能简化它时,我们必须显式地声明这些组:

Integer[][] groups={ { 5700, 5750 }, {5800, 5810}, {5802, 5812}, {5803, 5813} };

Map<Integer, Integer[]> type2group = Arrays.stream(groups)
    .collect(HashMap::new, (m,g) -> Arrays.stream(g).forEach(i->m.put(i, g)), Map::putAll);

ArrayList<A> finalList = aList.stream()
    .map(a -> a.getMyList().stream().collect(Collectors.collectingAndThen(
        Collectors.groupingBy(b -> type2group.get(b.getType())),
        group2b -> Arrays.stream(groups)
            .map(g -> group2b.getOrDefault(g, Collections.emptyList()))
            .map(listB -> getAWithGroupList(a, listB))
            .collect(Collectors.toList()))))
    .collect(ArrayList::new, List::addAll, List::addAll);

或者,以下代码更紧凑,但效率较低,因为它将多次处理数据(遍历每个组的所有
B
s,并在组内执行线性搜索):

Integer[][]组={{57005750}、{58005810}、{58025812}、{58035813};
List finalList=aList.stream().flatMap(a->Arrays.stream(组)
.map(g->getAWithGroupList(a,a.getMyList().stream())
.filter(b->Arrays.asList(g).contains(b.getType())
.collect(收集器.toList()))
.collect(Collectors.toList());
如果可能有缺席的组,并且您不想为它们设置空列表,您可以将其更改为

List<A> finalList = aList.stream().flatMap(a -> Arrays.stream(groups)
        .map(g -> a.getMyList().stream()
            .filter(b -> Arrays.asList(g).contains(b.getType()))
            .collect(Collectors.toList()))
        .filter(l -> !l.isEmpty())
        .map(l -> getAWithGroupList(a, l)))
    .collect(Collectors.toList());
List finalList=aList.stream().flatMap(a->Arrays.stream(组)
.map(g->a.getMyList().stream())
.filter(b->Arrays.asList(g).contains(b.getType())
.collect(收集器.toList())
.filter(l->!l.isEmpty())
.map(l->getAWithGroupList(a,l)))
.collect(Collectors.toList());

系统出现问题
myList
是空的,
myList.stream()
也是空的@dorukayhan我在列表中添加了虚拟数据。顺便说一句,这个问题似乎更适合。哦,我不知道。无论如何,我会选择包含这两种可能性的枚举方法。枚举将有一个方法,如“fromInt(Integer type)”,并将返回一个枚举值。然后,我将按枚举类型对流元素进行分组,并为每个组应用“getAWithGroupList()”方法。如果Java8中有可能内联执行多个过滤器并将结果作为列表列表获取,那么它将使结果更加清晰,而不是在不同的组列表中获取结果<代码>a.getMyList.stream().filter(-).filter(-).filter(-).collect(Collectors.toList())顺便说一句,我们无法创建通用数组新列表[]@UmairAnsari您可以使用
数组.asList(groupA,groupB,groupC,groupD)
代替数组:
for(List group:array.asList(groupA,groupB,groupC,groupD)){…
谢谢您的回答。我有
对象的列表a
。“我的值存储在
aList
中,您并不是在迭代它。@Umair Ansari:您应该仔细看看(或者试着运行它)。这两种解决方案都是迭代的,如前所述,第二种解决方案甚至会多次遍历它,这就是它效率较低的原因。还有一个提示:每个浏览器都有一个搜索功能,所以如果你看不到它,让浏览器突出显示出现的
aList
…在ObjectA来自的第一个解决方案中?我需要把这个对象添加到Advistor中。你是对的,我被你的示例代码误导了,它只有一个代码> < /Calp>实例(并且没有考虑<代码> A/<代码>的其他属性,除了被改写的<代码> MyList,它被<代码>克隆()/<代码>所保留。我修正了答案。
Integer[][] groups={ { 5700, 5750 }, {5800, 5810}, {5802, 5812}, {5803, 5813} };

Map<Integer, Integer[]> type2group = Arrays.stream(groups)
    .collect(HashMap::new, (m,g) -> Arrays.stream(g).forEach(i->m.put(i, g)), Map::putAll);

ArrayList<A> finalList = aList.stream()
    .map(a -> a.getMyList().stream().collect(Collectors.collectingAndThen(
        Collectors.groupingBy(b -> type2group.get(b.getType())),
        group2b -> Arrays.stream(groups)
            .map(g -> group2b.getOrDefault(g, Collections.emptyList()))
            .map(listB -> getAWithGroupList(a, listB))
            .collect(Collectors.toList()))))
    .collect(ArrayList::new, List::addAll, List::addAll);
ArrayList<A> finalList = aList.stream()
    .map(a -> a.getMyList().stream().collect(Collectors.collectingAndThen(
        Collectors.groupingBy(b -> type2group.get(b.getType())),
        group2b -> Arrays.stream(groups)
            .map(g -> group2b.get(g)).filter(Objects::nonNull)
            .map(listB -> getAWithGroupList(a, listB))
            .collect(Collectors.toList()))))
    .collect(ArrayList::new, List::addAll, List::addAll);
Integer[][] groups={ { 5700, 5750 }, {5800, 5810}, {5802, 5812}, {5803, 5813} };

List<A> finalList = aList.stream().flatMap(a -> Arrays.stream(groups)
        .map(g -> getAWithGroupList(a, a.getMyList().stream()
            .filter(b -> Arrays.asList(g).contains(b.getType()))
            .collect(Collectors.toList()))))
    .collect(Collectors.toList());
List<A> finalList = aList.stream().flatMap(a -> Arrays.stream(groups)
        .map(g -> a.getMyList().stream()
            .filter(b -> Arrays.asList(g).contains(b.getType()))
            .collect(Collectors.toList()))
        .filter(l -> !l.isEmpty())
        .map(l -> getAWithGroupList(a, l)))
    .collect(Collectors.toList());