如何在Java 8 Stream API中使用org.w3c.dom.NodeList?

osc*_*ter 23 java dom

我相信接口org.w3c.dom.NodeList缺少一个stream()函数来利用Java 8的Stream API的好处.考虑引入默认方法以确保向后兼容性,我无法理解为什么此接口没有stream()功能.

所以我的问题是:

  • 如何NodeList结合Stream API使用?
  • 如果不鼓励这样做,原因是什么?

提前致谢!

编辑:我目前正在使用此实用程序包装器:

private static Stream<Node> nodeStream(NodeList list) {
    List<Node> nodes = new ArrayList<>();

    for (int n = 0; n < list.getLength(); ++n) {
        nodes.add(list.item(n));
    }

    return nodes.stream();
}
Run Code Online (Sandbox Code Playgroud)

Ian*_*rts 51

The DOM is a strange beast, the API is defined in a language-independent way by the W3C and then mapped into various different programming languages, so Java can't add anything Java-specific to the core DOM interfaces that wasn't part of the DOM spec in the first place.

So while you can't use a NodeList as a stream, you can easily create a stream from a NodeList, using e.g.

Stream<Node> nodeStream = IntStream.range(0, nodeList.getLength())
                                   .mapToObj(nodeList::item);
Run Code Online (Sandbox Code Playgroud)

However, there is one big caveat - a DOM NodeList is live, and reflects changes to the original DOM tree since the list was created. If you add or remove elements in the DOM tree they may magically appear or disappear from existing NodeLists, and this may cause strange effects if this happens mid-iteration. If you want a "dead" node list you'll need to copy it into an array or list, as you are doing already.


Ste*_*n C 7

考虑到引入默认方法以确保向后兼容,我无法理解为什么此接口不具有stream()函数。

该接口是在Java 8存在之前定义的。由于StreamJava 8之前不存在,因此NodeList 无法支持它。

如何将NodeList与Stream API结合使用?

你不能 至少不是直接。

如果不建议这样做,原因是什么?

它不是“粘性的”。而是不支持它。

主要原因是历史。往上看。

负责指定org.w3c.domJava API的人员(即W3联盟)可能会推出对Java 8更友好的API新版本。但是,这会带来许多新的兼容性问题。新版本的API将不会与当前版本进行二进制兼容,也不会与Java 8之前的JVM兼容。


但是,这比让W3联盟更新API更为复杂。

DOM API是在CORBA IDL中定义的,而Java API是通过将CORBA Java映射应用于IDL来“生成”的。该映射由OMG指定,而不是由W3联盟指定。因此,创建org.w3c.domAPI 的“ Java 8流友好”版本将需要使OMG更新以Stream了解CORBA Java映射(至少从CORBA兼容性角度来看这是有问题的)或断开Java API之间的连接和CORBA。

不幸的是,要在OMG世界中发现刷新IDL到Java映射所发生的事情(如果有的话)是困难的……除非您为OMG成员组织等服务。我不。

  • 除非我误解了您的意思,否则您的声明“由于Java 8之前不存在Stream,因此NodeList无法支持它”。该问题明确询问为什么未将默认方法添加到NodeList中-即类似于如何将默认流方法添加到Collection中。 (2认同)