我可以在Java中使用for-each迭代NodeList吗?

2022-08-31 19:47:53

我想在Java中迭代使用for-each循环。我让它与 for 循环和 do-while 循环一起工作,但不是每个循环。NodeList

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());
}

答案 1

此问题的解决方法是直截了当的,值得庆幸的是,您只需要实现一次。

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();
    }
  }
}

将此实用工具类添加到项目中并将 for 方法添加到源代码后,可以按如下方式使用它:staticimportXmlUtil.asList

for(Node n: asList(dom.getElementsByTagName("year"))) {
  …
}

答案 2

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

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++); 
        }
    };
}

然后像这样使用它:

NodeList nodeList = ...;
for (Node node : iterable(nodeList)) {
    // ....
}

或者等效地像这样:

NodeList nodeList = ...;
iterable(nodeList).forEach(node -> {
    // ....
});