使用Java8流2循环并从内部循环返回外部循环对象
我有这样一个函数:使用Java8流2循环并从内部循环返回外部循环对象,java,loops,for-loop,java-8,java-stream,Java,Loops,For Loop,Java 8,Java Stream,我有这样一个函数: 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) {
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;
}
使用流对我的需求来说是个坏主意吗?还是我走错了路?试试这样的方法:
返回bs.stream()
.过滤器(b->R的b实例)
.地图(b->(R)b)
.flatMap(r->r.getB().stream())
.filter(cObject->C的cObject实例)
.map(cObject->((C)cObject.getV())
.filter(vObject->vObject instanceof V)
.map(v->r.getXyz())
).findFirst().orElse(null);
更新
在评论中提到,最好将flatMap
替换为filter
,以下是较新的版本:
返回bs.stream()
.过滤器(b->R的b实例)
.地图(b->(R)b)
.filter(r->r.getB()
.stream()
.anyMatch(c->c的instanceof c&((c)c).getV()的instanceof V)
)
.map(R::getXyz)
.findFirst().orElse(null);
重新考虑instanceof
及其后的显式强制转换所需的检查,它们是你所看到的复杂性的根源。因此你基本上有一个P
的实例,其中包含一个对象列表,这些对象可能是R
的实例,如果任何这样的实例有一个C
,它有一个V
,你想返回R
的Xyz
?-这意味着您要过滤R
,然后映射到R
,然后过滤R.b
,过滤C.V
,最后收集R.xyz
-听起来很复杂?这是你的密码;)-对于所有这些神秘的名称,很难进行推理,特别是因为看起来那些P
和R
实例可以包含任何类型的列表(那些List bs=P.getB();
等等)。那真的有必要吗?不需要对方付费。由于要返回第一个匹配项,只需使用您已经知道的findFirst()
。不要使用forEach的forEach
@Naman,因为需要该实例。“我无法避免。”托马斯。对需要。对于命名约定,很抱歉。使用.filter(r->r.getB().stream().anyMatch(c->c instanceof c&((c)c).getV()instanceof V)).map(r::getXyz)来代替flatMap
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*/);