我正在使用第三方库,其中有两个非常相似的类没有实现接口。代码当前循环遍历项目列表,以使用这些类中的一个查找对象的第一个匹配项,然后将其转换为处理它的流。如果我可以将此代码转换为使用流并将其链接到我的其余代码,那将是很好的。
for (Component3Choice component: components) {
if (component instanceof OptionalComponent3Bean) {
OptionalComponent3Bean section = (OptionalComponent3Bean) component;
entryStream = section.getSection().getEntry().stream()
break;
}
else if (component instanceof RequiredComponent3Bean) {
RequiredComponent3Bean section = (RequiredComponent3Bean) component;
entryStream = section.getSection().getEntry().stream();
break;
}
}
... do something with the stream ...
components.stream()
.filter(entry -> entry instanceof OptionalComponent3Bean
|| entry instanceof RequiredComponent3Bean)
.findFirst()
.map( {{ cast entry }} )
.map( castedEntry.getSection().getEntry())
... continue on with my processing
是否可以根据流中的前一个过滤器转换条目?
答案 0 :(得分:3)
不,没有任何东西可以帮助你摆脱糟糕的设计,这就是你正在反抗的。
如果您需要在许多地方复制类似于此的样板,您可以通过包装器强制使用通用接口。 否则,我想你能做的最好的就是
static private IDontKnow getStream(Component3Choice c3c) {
if (c3c instanceof OptionalComponent3Bean) {
return ((OptionalComponent3Bean)c3c).getStream();
} else if (c3c instanceof RequiredComponent3Bean) {
return ((RequiredComponent3Bean)c3c).getStream();
} else {
return null;
}
}
components.stream()
.map(x -> getStream(x))
.filter(x -> x!=null)
.findFirst()
.map(x -> x.getEntry().stream());
... continue on with yout processing
答案 1 :(得分:1)
不是最漂亮的代码,但你可以这样做:
components.stream()
.filter(entry -> entry instanceof OptionalComponent3Bean
|| entry instanceof RequiredComponent3Bean)
.map(entry -> {
if ((entry instanceof OptionalComponent3Bean)
return ((OptionalComponent3Bean) entry).getSection().getEntry().stream();
else
return ((RequiredComponent3Bean) entry).getSection().getEntry().stream();
})
.findFirst();
这将返回Optional<Stream<Something>>
。
请注意,findFirst
必须是最后一次操作,因为它是终端。