我正在尝试浏览 3 个列表(嵌套的三重 for 循环)并根据匹配设置一些值。下面是一个类表示以及我正在迭代并基于匹配进行设置的三重 for 循环。
我的问题是,如何使用流 API 替换下面包含的循环?
我是 Java 新手,正在尝试了解 Java 8 功能。任何帮助将不胜感激。谢谢你,祝你有美好的一天!
下面列出了涉及的类和我想用 Java 8 流 API 替换的循环:
提前非常感谢大家!祝你有美好的一天!
课程:
class B {
Long Id;
Long x;
String y;
Long z;
}
class A {
private Long Id;
private List<B> bList;
}
class C {
private Long Id;
private List<Long> bIds;
private String y;
private Long z;
}
嵌套 for 循环:
void f(List<A> aList, List<C> cList) {
for(A a : aList) {
List<B> bList= a.getBList();
for(B b : bList) {
for(C c : cList) {
if(a.getId().equals(c.getId()) && c.getBIds().contains(b.getId())) {
b.setZ(c.getZ());
b.setY(c.getY());
}
}
}
}
}
我倾向于同意另一个答案,即不要使流的逻辑过于复杂或混淆;但是从技术上来说你可以做这样的事情:
void f(List<A> aList, List<C> cList) {
Map<Long, C> cIdToCMap = cList.stream().collect(Collectors.toMap(C::getId, item -> item));
aList.stream().forEach(a -> a.getBList().stream()
.filter(b -> cIdToCMap.get(a.getId()).getBIds().contains(b.getId())).forEach(b -> {
C c = cIdToCMap.get(a.getId());
b.setY(c.getY());
b.setZ(c.getZ());
}));
}
我做了一些预处理,将 C 按 ID 放入映射中,以减少额外循环的需要。但你本可以这样做:
void f(List<A> aList, List<C> cList) {
aList.stream().forEach(a -> a.getBList().stream().forEach(b -> {
cList.stream().filter(c -> c.getId().equals(a.getId()) && c.getBIds().contains(b.getId())).forEach(c -> {
b.setY(c.getY());
b.setZ(c.getZ());
});
}));
}
请记住,第二个最接近您的代码,如果发现重复的 ID,它会覆盖值。在此代码和您的代码中,最后一场比赛获胜。