【发布时间】:2020-02-25 15:11:23
【问题描述】:
我有这样的功能:
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;
}
我想通过使用 java 8 流来更改代码。 是否有可能,因为我从第二个循环内的第一个循环返回属性。
我尝试了这两种方法。但它没有任何帮助,而且似乎是错误的:
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*/);
对我的要求使用流是个坏主意吗?还是我走错了路?
【问题讨论】:
-
重新考虑
instanceof所需的那些检查以及之后的显式转换,它们是您正在查看的复杂性的根源。 -
所以你基本上有一个
P的实例,它包含一个可能是R实例的对象列表,如果任何这样的实例有一个C有一个V你想要返回R的Xyz? - 这意味着您将过滤R,然后映射到R,然后过滤R.b以获得C.V,最后收集R.xyz。 - 听起来很复杂?好吧,这是你的代码 ;) - 对于所有这些神秘的名称,很难推理,特别是因为看起来好像那些P和R实例可以包含任何类型的列表(那些List<Object> bs = p.getB();等)。这真的有必要吗? -
不需要收集。由于您要返回第一个匹配项目,因此只需使用您已经证明知道的
findFirst()。不要使用forEach。 -
@Naman 的实例是必需的。无法避免。
-
@Thomas。是的..需要。抱歉命名约定。
标签: java loops for-loop java-8 java-stream