如何在 Java 8 流中投射具有不同 类 的对象?
How to cast objects with different classes in a Java 8 stream?
用例
我正在使用第 3 方库,其中有两个非常相似的 类 没有实现接口。该代码当前循环遍历项目列表,以使用其中一个 类 查找对象的第一次出现,然后将其转换为处理它的流。如果我可以将此代码转换为使用流并将其链接到我的其余代码,那就太好了。
当前代码
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
问题
是否可以根据流中的前一个过滤器投射条目?
不是最漂亮的代码,但你可以做到:
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();
这会 return 一个 Optional<Stream<Something>>
。
请注意,findFirst
必须是最后一个操作,因为它是终止操作。
不,没有什么可以使您免于糟糕的设计,这似乎是您正在与之抗争的。
如果您需要在许多地方复制与此类似的样板文件,您可以通过包装器强制使用通用接口。
否则,我想你能做的最好的就是
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
用例
我正在使用第 3 方库,其中有两个非常相似的 类 没有实现接口。该代码当前循环遍历项目列表,以使用其中一个 类 查找对象的第一次出现,然后将其转换为处理它的流。如果我可以将此代码转换为使用流并将其链接到我的其余代码,那就太好了。
当前代码
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
问题
是否可以根据流中的前一个过滤器投射条目?
不是最漂亮的代码,但你可以做到:
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();
这会 return 一个 Optional<Stream<Something>>
。
请注意,findFirst
必须是最后一个操作,因为它是终止操作。
不,没有什么可以使您免于糟糕的设计,这似乎是您正在与之抗争的。
如果您需要在许多地方复制与此类似的样板文件,您可以通过包装器强制使用通用接口。 否则,我想你能做的最好的就是
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