为什么这个流没有返回任何元素?

6

我尝试将以下代码写成流式代码:

AbstractDevice myDevice = null;

for (AbstractDevice device : session.getWorkplace().getDevices()) {

    if (device.getPluginconfig().getPluginType().getId() == 1) {
        myDevice =  device;
    }

}

这段代码运行良好。

但是,当我像这样重写它时,它就不再工作了:

myDevice = session.getWorkplace().getDevices().stream()
                  .filter(s -> s.getPluginconfig().getPluginType().getId() == 1)
                  .findFirst().get();

我从流中获得的 Optional 没有值。为什么会这样?

编辑

当我尝试以下操作时(仍然从 getDevices() 返回两个设备):

 List<AbstractDevice> testList = session.getWorkplace().getDevices()
                                        .stream().collect(Collectors.toList());

testList为空。看起来我的设备List的流程出了问题?

这是一个JavaEE应用程序,我从相应的实体中获取我的设备:

@ManyToMany(cascade = {CascadeType.PERSIST, CascadeType.MERGE, CascadeType.REFRESH})
@JoinTable(name = "Workplace_AbstractDevice",
            joinColumns = {
                @JoinColumn(name = "Workplace", referencedColumnName = "ID")
            },
            inverseJoinColumns = {
                @JoinColumn(name = "AbstractDevice", referencedColumnName = "ID")
            })
@OrderColumn
private List<AbstractDevice> devices = new ArrayList<AbstractDevice>();


public List<AbstractDevice> getDevices() {
    return devices;
}

7
你能提供一个简短但完整的程序来展示问题吗?如果无法重现,很难进行诊断。 - Jon Skeet
4
原始代码会从列表中获取最后一个匹配项,而流式代码将获取第一个匹配项。我不知道这是否是本例中的问题。 - WillShackleford
1
从session.getWorkplace.getDevices()获得的列表中有两个对象,你确定吗?此外,你提供的非流式解决方案似乎是查找最后一个匹配项而不是第一个。 - Pshemo
6
如果没有代码可以复现问题,那么这个问题无法回答。我们只能猜测,这并不是很有效。请提供 SSCCE,否则这个问题可能会被关闭。请注意不要改变原来的意思。 - Pshemo
2
听起来你程序的另一部分非常重要,因为它提供的数据没有被正确读取...如果你回到原始代码,它仍然能工作吗? - Jon Skeet
显示剩余4条评论
1个回答

7
看起来你正在使用 EclipseLink 2.6 版本之前的版本,并且遇到了 Bug#433075。这个 devices 字段被 IndirectList(通过反射)替换,它继承了 Vector 类并执行惰性初始化。它是为旧版 Java 编写的,该版本没有 stream() 方法,因此在未初始化列表上调用 stream() 实际上会返回一个空流。

这个bug已经修复,因此你可能需要将EclipseLink更新到2.6版本。在EclipseLink 2.6中,另一个类在JDK 1.8上运行时使用,它对流处理更友好。


谢谢!但不幸的是,在使用@OrderColumn时,2.6仍然存在一个错误。 - Adrian Krebs
1
@Swiss_Codeaholic,我明白了。很遗憾。你可以调用类似devices.isEmpty()的方法来强制初始化,但我建议在下一个版本发布之前不要使用流API。 - Tagir Valeev
是的,我现在放弃了。有点难过,因为它仍然没有得到支持...我的意思是JDK8已经发布一段时间了。无论如何,感谢@Tagir Valeev的帮助! - Adrian Krebs
谢谢,我之前使用的是eclipselink v2.5.0,出现了这个问题,但是升级到版本2.6.0后,问题解决了。 - Javier Larios

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接