流2使用java8循环,并从内部循环返回外部循环对象



我有一个这样的函数:

public static Xyz getXyz(P p) {
if (p == null) {
return null;
}
List<Object> bs = p.getB();
if (CollectionUtils.isEmpty(Bs)) {
return null;
}
for (Object b : bs) {
if (b instanceof R) {
R r = (R) b;
List<Object> cObjects = r.getB();
for (Object cObject : cObjects) {
if (cObject instanceof C) {
C c = (C) cObject;
Object vObject = cObject.getV();
if (vObject instanceof V) {
return r.getXyz();
}
}
}
}
}
return null;
}

我想通过使用java8流来更改代码。这可能吗,因为我正在从第二个循环中的第一个循环返回属性。

我试过这两种方法。但这无济于事,而且似乎是错误的:

public static Xyz getXyz(P p) {
if (p == null) {
return null;
}
List<Object> bs = p.getB();
if (CollectionUtils.isEmpty(Bs)) {
return null;
}
Xyz xyz = null;
bs.stream()
.filter(b -> (b instanceof R))
.map(b -> (R) b).forEach(r -> {
List<Object> cObjects = = r.getB();
Optional vOptional= cObjects.stream()
.filter(cObjects -> (cObjects instanceof C))
.map(cObjects -> ((C) cObjects).getV())
.filter(vObject -> (vObject instanceof V)).findFirst();
if(vOptional.isPresent()){
xyz =  r.getXyz();
return;
}
});
return xyz;
}

我试过了,但我不认为我能收集到我需要的价值

bs.stream()
.filter(b -> (b instanceof R))
.flatMap(b -> ((R) b).getB().stream())
.filter(cObject -> (cObject instanceof C))
.map(cObject -> ((C) cObject).getV())
.filter(vObject -> (vObject instanceof V))
.collect(/*no idea if I can collect the value I desire*/);

对于我的需求,使用流是个坏主意吗?还是我走错了路?

试试这样的东西:

return bs.stream()
.filter( b -> b instanceof R)
.map(b -> (R) b)
.flatMap(r -> r.getB().stream()
.filter(cObject -> cObject instanceof C)
.map(cObject -> ((C) cObject).getV())
.filter(vObject -> vObject instanceof V)
.map(v -> r.getXyz())
).findFirst().orElse(null);

更新

Holger在评论中提到,用filter替换flatMap会很好,所以这里有更新的版本:

return bs.stream()
.filter(b -> b instanceof R)
.map(b -> (R) b)
.filter(r -> r.getB()
.stream()
.anyMatch(c -> c instanceof C && ((C) c).getV() instanceof V)
)
.map(R::getXyz)
.findFirst().orElse(null);

最新更新