共同学习Java源代码-数据结构-PriorityQueue类(五)

    public Iterator iterator() {
        return new Itr();
    }
这个是迭代器方法 

    private final class Itr implements Iterator {

这个是实现了迭代器接口的内部迭代器类

        private int cursor = 0;

这个是迭代光标

        private int lastRet = -1;

这个是最近一次返回的元素在数组中的下标

        private ArrayDeque forgetMeNot = null;

这个表示迭代过程中 一部分没有访问到的元素放在这里 等正常迭代完成 再迭代这里

        private E lastRetElt = null;

上一次访问的元素

        private int expectedModCount = modCount;
迭代器的修改次数 和 外部类的修改次数同步

        public boolean hasNext() {
            return cursor < size ||
                (forgetMeNot != null && !forgetMeNot.isEmpty());
        }
这个是判断是否还剩余元素的方法 判断光标是否小于size或forgetMeNot是否不为空

        @SuppressWarnings("unchecked")
        public E next() {
            if (expectedModCount != modCount)
                throw new ConcurrentModificationException();
            if (cursor < size)
                return (E) queue[lastRet = cursor++];
            if (forgetMeNot != null) {
                lastRet = -1;
                lastRetElt = forgetMeNot.poll();
                if (lastRetElt != null)
                    return lastRetElt;
            }
            throw new NoSuchElementException();
        }

这个是迭代下一个元素的方法

先判断如果两个修改次数不一致 就抛出并发异常 

判断如果光标小于size 就返回数组的下一个元素 光标自增后赋给lastRet 

判断如果forgetMeNot不为空

lastRet赋为-1 lastRetElt赋为forgetMeNot的第一个元素 并且从这个双向队列中删除第一个元素 判断这个元素不为空就返回

最后如果没有下一个元素了 就抛出异常

        public void remove() {
            if (expectedModCount != modCount)
                throw new ConcurrentModificationException();
            if (lastRet != -1) {
                E moved = PriorityQueue.this.removeAt(lastRet);
                lastRet = -1;
                if (moved == null)
                    cursor--;
                else {
                    if (forgetMeNot == null)
                        forgetMeNot = new ArrayDeque<>();
                    forgetMeNot.add(moved);
                }
            } else if (lastRetElt != null) {
                PriorityQueue.this.removeEq(lastRetElt);
                lastRetElt = null;
            } else {
                throw new IllegalStateException();
            }
            expectedModCount = modCount;
        }

    }

最后是迭代删除的方法

先判断两个修改次数是否一致 不一致就抛出并发异常

如果lastRet不为-1 说明队列还在遍历 就调用外部类的removeAt方法 将lastRet处的元素删除 并赋给临时变量moved

将lastRet设为-1

判断moved为空 光标自减 如果moved不为空 就判断forgetMeNot是否为空 为空就创建新的双向队列实例 将moved放进去 其实这个forgetMeNot就是个垃圾桶 

 如果lastRet为-1 单lastRetElt不为空 就调用外部类的方法删除这个对象 

如果上述判断都不成立就抛出异常

最后将两个修改次数统一

你可能感兴趣的:(Java)