如何在Java 8流中转换具有不同类的对象?

时间:2015-03-11 13:54:57

标签: java java-8 java-stream

使用案例

我正在使用第三方库,其中有两个非常相似的类没有实现接口。代码当前循环遍历项目列表,以使用这些类中的一个查找对象的第一个匹配项,然后将其转换为处理它的流。如果我可以将此代码转换为使用流并将其链接到我的其余代码,那将是很好的。

当前代码

    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

问题

是否可以根据流中的前一个过滤器转换条目?

2 个答案:

答案 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必须是最后一次操作,因为它是终端。