我已经使用Java 8流编写了代码,但尝试重构。
我已使用不同的条件过滤列表并将其存储到新列表中。有没有办法一次过滤所有条件并将结果组存储到列表中。我不知道如何解释。
这是我的代码,只需要重构它。
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;
}
任何帮助或建议都将不胜感激。
感谢。
答案 0 :(得分:1)
简单。用方法包装重复代码:
private List<B> listifyAndfilter(A a, Predicate<List<B>> check){
return a.getMyList.stream().filter(check).collect(Collectors.toList());
}
然后你可以这样做:
List<B> groupA = listifyAndFilter(a, b -> b.getType() == 5700 || b.getType() == 5750),
groupB = listifyAndFilter(a, b -> b.getType() == 5800 || b.getType() == 5810),
groupC = listifyAndFilter(a, b -> b.getType() == 5802 || b.getType() == 5812),
groupD = listifyAndFilter(a, b -> b.getType() == 5803 || b.getType() == 5813);
注意行末尾的逗号。
无关但有用:您还可以合并这些if语句:
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));
}
进入这个for-each循环:
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));
答案 1 :(得分:1)
最大的障碍是你的标准背后的基本原理是未知的。因此,当我们无法简化它时,我们必须明确声明这些组:
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.getType
的结果)到所需组的标识符的映射,这只是我们的完整group
说明符的子数组(实际的)组标识符的类型是无关紧要的,因为我们将在以后遇到相同的对象,因此数组没有equals
方法的事实在这里并不重要。)
第二步为每个B
执行A
个实例的分组,并组装finalList
。
请注意,如果没有组,上述解决方案将为它们创建空列表。如果您不想拥有它们,可以将解决方案的最后一步更改为
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);
或者,以下代码更紧凑,但效率更低,因为它将多次处理数据(遍历每个组的所有B
并在组内执行线性搜索):
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());