您的位置:首页 > 理论基础 > 数据结构算法

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

2018-01-14 17:41 337 查看
    public Iterator<E> iterator() {

        return new Itr();

    }

这个是迭代器方法 

    private final class Itr implements Iterator<E> {
这个是实现了迭代器接口的内部迭代器类

        private int cursor = 0;

这个是迭代光标
        private int lastRet = -1;

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

        private ArrayDeque<E> 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不为空 就调用外部类的方法删除这个对象 

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

最后将两个修改次数统一
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: