我可以在Java中使用for-each遍历NodeList吗?

use*_*834 35 java xml dom

我想NodeList在Java中使用for-each循环进行迭代.我让它使用for循环和do-while循环但不适用于每个.

NodeList nList = dom.getElementsByTagName("year");
do {
    Element ele = (Element) nList.item(i);
    list.add(ele.getElementsByTagName("MonthId").item(0).getTextContent());
    i++;
} while (i < nList.getLength());

NodeList nList = dom.getElementsByTagName("year");

for (int i = 0; i < nList.getLength(); i++) {
    Element ele = (Element) nList.item(i);
    list.add(ele.getElementsByTagName("MonthId").item(0).getTextContent());
}
Run Code Online (Sandbox Code Playgroud)

Hol*_*ger 44

这个问题的解决方法是直截了当的,幸运的是,你必须只实现一次.

import java.util.*;
import org.w3c.dom.*;

public final class XmlUtil {
  private XmlUtil(){}

  public static List<Node> asList(NodeList n) {
    return n.getLength()==0?
      Collections.<Node>emptyList(): new NodeListWrapper(n);
  }
  static final class NodeListWrapper extends AbstractList<Node>
  implements RandomAccess {
    private final NodeList list;
    NodeListWrapper(NodeList l) {
      list=l;
    }
    public Node get(int index) {
      return list.item(index);
    }
    public int size() {
      return list.getLength();
    }
  }
}
Run Code Online (Sandbox Code Playgroud)

将此实用程序类添加到项目并将static importXmlUtil.asList方法添加到源代码后,可以像下面这样使用它:

for(Node n: asList(dom.getElementsByTagName("year"))) {
  …
}
Run Code Online (Sandbox Code Playgroud)


Tho*_*sch 11

我知道派对已经晚了,但是......
从Java-8开始,你可以通过使用lambda表达式(用于创建新的)和默认方法(for )来更简洁地编写@ RayHulha的解决方案:IterableIterator.remove

public static Iterable<Node> iterable(final NodeList nodeList) {
    return () -> new Iterator<Node>() {

        private int index = 0;

        @Override
        public boolean hasNext() {
            return index < nodeList.getLength();
        }

        @Override
        public Node next() {
            if (!hasNext())
                throw new NoSuchElementException();
            return nodeList.item(index++); 
        }
    };
}
Run Code Online (Sandbox Code Playgroud)

然后像这样使用它:

NodeList nodeList = ...;
for (Node node : iterable(nodeList)) {
    // ....
}
Run Code Online (Sandbox Code Playgroud)

或者相当于这样:

NodeList nodeList = ...;
iterable(nodeList).forEach(node -> {
    // ....
});
Run Code Online (Sandbox Code Playgroud)

  • 或者`return()-&gt; IntStream.range(0,nodeList.getLength()).mapToObj(nodeList :: item).iterator();` (3认同)

Ray*_*lha 8

public static Iterable<Node> iterable(final NodeList n) {
  return new Iterable<Node>() {

    @Override
    public Iterator<Node> iterator() {

      return new Iterator<Node>() {

        int index = 0;

        @Override
        public boolean hasNext() {
          return index < n.getLength();
        }

        @Override
        public Node next() {
          if (hasNext()) {
            return n.item(index++);
          } else {
            throw new NoSuchElementException();
          }  
        }

        @Override
        public void remove() {
          throw new UnsupportedOperationException();
        }
      };
    }
  };
}
Run Code Online (Sandbox Code Playgroud)


Cal*_*lin 7

为科学添加快乐的小 kotlin 版本:

fun NodeList.forEach(action: (Node) -> Unit) {
    (0 until this.length)
            .asSequence()
            .map { this.item(it) }
            .forEach { action(it) }
}
Run Code Online (Sandbox Code Playgroud)

然后可以使用它 nodeList.forEach { do_something_awesome() }


Eel*_*Lee 5

由于NodeList只是一个接口,你可以创造条件,同时实现一类NodeListIterable,从而来遍历它.