Can I iterate through a NodeList using for-each in Java?

前端 未结 10 1154
没有蜡笔的小新
没有蜡笔的小新 2020-12-09 00:55

I want to iterate through a NodeList using a for-each loop in Java. I have it working with a for loop and a do-while loop but not for-each.

Node         


        
10条回答
  •  情书的邮戳
    2020-12-09 01:38

    If the current DOM element is removed (via JavaScript) while iterating a NodeList (created from getElementsByTagName() and maybe others), the element will disappear from the NodeList. This makes correct iteration of the NodeList more tricky.

    public class IteratableNodeList implements Iterable {
        final NodeList nodeList;
        public IteratableNodeList(final NodeList _nodeList) {
            nodeList = _nodeList;
        }
        @Override
        public Iterator iterator() {
            return new Iterator() {
                private int index = -1;
                private Node lastNode = null;
                private boolean isCurrentReplaced() {
                    return lastNode != null && index < nodeList.getLength() &&
                           lastNode != nodeList.item(index);
                }
    
                @Override
                public boolean hasNext() {
                    return index + 1 < nodeList.getLength() || isCurrentReplaced();
                }
    
                @Override
                public Node next() {
                    if (hasNext()) {
                        if (isCurrentReplaced()) {
                            //  It got removed by a change in the DOM.
                            lastNode = nodeList.item(index);
                        } else {
                            lastNode = nodeList.item(++index);
                        }
                        return lastNode;
                    } else {
                        throw new NoSuchElementException();
                    }
                }
    
                @Override
                public void remove() {
                    throw new UnsupportedOperationException();
                }
            };
        }
    
        public Stream stream() {
            Spliterator spliterator =
                Spliterators.spliterator(iterator(), nodeList.getLength(), 0);
            return StreamSupport.stream(spliterator, false);
        }
    }
    

    Then use it like this: new IteratableNodeList(doc.getElementsByTagName(elementType)). stream().filter(...)

    Or: new IteratableNodeList(doc.getElementsByTagName(elementType)).forEach(...)

提交回复
热议问题