LinkedList.java 自嗨

肯定是有错的。。。说来惭愧,有些方法至今没有用过,比起ArrayList,好像LinkedList没有提供关于子表的方法。

(没有标号怎么实现截取,在Node里面再加一个标号吗哈哈哈哈)

package java.util;
import java.util.function.Consumer;
public class LinkedList<E>
    extends AbstractSequentialList<E>
    /*双链表,在{1}处有提到原因,且不带头结点,原因在{2}处*/
    implements List<E>, Deque<E>, Cloneable, java.io.Serializable
{
		//记录链表中元素的个数
		//size对于链表的实现并不是必须的
		//用transient修饰
    transient int size = 0;

    //存储头结点
    //利用了transient修饰
    transient Node<E> first;
    //节点类的定义:(可见这是一个双链表)
    /*{1}:
    public static class Node<E> {
    	E item;
    	Node<E> next;
    	Node<E> prev;
    	
    	Node(Node<E> prev, E element, Node<E> next) {
    		this.item = element;
    		this.next = next;
    		this.prev = prev;
    	}
    }
    */

    //存储最后一个节点
    //利用了transient修饰
    transient Node<E> last;

    //创建一个空的链表
    //从构造方法可见,该链表不带头结点
    //{2}:
    public LinkedList() {
    }

	//根据Collection创建一个双链表
	//顺序同Iterator遍历的顺序
    public LinkedList(Collection<? extends E> c) {
        this();
        addAll(c);//添加,将在{3}处说明
    }

	//{6}
    /*添加e作为第一个节点*/
    /*
    我的话可能就是这样写:
    Node<E> q = new Node(null, e, first);
    if (first != null) //非空
    	last = q;
    else 	
    	first.prev = q;
    first = q;
    */
    private void linkFirst(E e) {
        final Node<E> f = first;//将原先的第一个节点暂存
        final Node<E> newNode = new Node<>(null, e, f);//创建一个新节点
        first = newNode;//将第一个节点的引用改变
        if (f == null)
            last = newNode;//如果为空,最后一个节点就是第一个节点
        else
            f.prev = newNode;//不为空,原先第一个节点的后一个节点是新节点
        size++;//将size + 1
        modCount++;//将modCount + 1
    }

	//{7}
	/*尾插入*/
    void linkLast(E e) {
        final Node<E> l = last;//暂存最后一个节点
        final Node<E> newNode = new Node<>(l, e, null);//创建新节点
        last = newNode;//改变最后一个节点
        if (l == null)
            first = newNode;//如果为空,第一个节点就是最后一个节点
        else
            l.next = newNode;//不为空,原先的最后一个节点的后一个是新节点
        size++;//size + 1
        modCount++;//modCount + 1
    }

    /*如果让我写:
    分析情况如下:
    1.表空(不可能)
    2.表非空。头插---调用头插
    3.表非空。中间插入---写中间插入代码
    4.表非空。尾插---不可能(因为不是循环链表)
    关于第四点我想说的是:循环链表只有中间插入的概念,控制相对方便。
    而且尾插的话,直接插头结点之前不就行了。
    
    实际上设置头结点就是这个原因(对于某些链表)
    可以将头插代码和中间插入代码合并,且中间插入代码本来就可以和尾插入代码合并
    而空表插入,由于有了一个头结点的存在,而变成了尾插。
    使三种插入情况相同(实际上应该是四种)。
    if (succ.prev == null)
    	linkFirst(e);
    else {
    	Node<E> q = new Node(succ.prev, e, succ);
    	succ.prev.next = q;
    	succ.prev = q;
    } 
   	链表很基础,但是容易迷
   	凡是引用类型的变量,其最后一个点前面的都是要被运算出来的
   	最后一个‘.’之后的才是赋值的对象
    */
    void linkBefore(E e, Node<E> succ) {
        final Node<E> pred = succ.prev;//succ为空第一句开始就报错
        final Node<E> newNode = new Node<>(pred, e, succ);//创建新节点
        succ.prev = newNode;//succ前一个 赋值为 新节点
        if (pred == null)//如果succ原先的前一个为空(说明succ是第一个节点)
            first = newNode;//相当于头插
        else
            pred.next = newNode;//不为空,succ前一个的next赋值为新节点
        size++;//size + 1
        modCount++;//modCount + 1
    }

	//{4}
	//实际上的作用是将f和f之前的节点删除
	//(但是size--就说明只能是头结点)
    private E unlinkFirst(Node<E> f) {
        final E element = f.item;//将f的item域暂存
        final Node<E> next = f.next;//将f后一个节点暂存
        f.item = null;//f.item赋值null
        f.next = null;
        //上面两行是为了gc
        first = next;//first赋值next(看到这里我才懂方法的意思)
        if (next == null)//如果next是null(说明链表中只有f一个节点)
            last = null;
        else
            next.prev = null;//不为空,新的第一节点是头结点,所以prev域为空
        size--;//大小 - 1
        modCount++;//modCount + 1
        return element;//将移除的元素返回
    }

	//{5}
	//将l在内的之后的节点统统删除,返回l的item域
	//(但是size--就能说明只能是尾结点,不然size出错)
    private E unlinkLast(Node<E> l) {
        final E element = l.item;//暂存最后一个节点
        final Node<E> prev = l.prev;//暂存将来的最后一个节点
        l.item = null;//触发gc
        l.prev = null;//触发gc
        last = prev;//last指针指向prev
        if (prev == null)//如果只有一个节点
            first = null;//移除之后first也是null了
        else
            prev.next = null;//将倒数第二个节点指向最后一个节点的引用断开
        size--;//size - 1
        modCount++;//modCount + 1
        return element;//返回暂存节点
    }

	//{9}
	//将节点从这个链表中删除
	//为什么不先直接判断然后调用其他头删尾删的方法呢?
	//就因为三种操作有共同性?
    E unlink(Node<E> x) {
        final E element = x.item;//将x的item域暂存
        final Node<E> next = x.next;//将x的下一个暂存
        final Node<E> prev = x.prev;//将x的上一个暂存

        if (prev == null) {//如果是第一个节点
            first = next;//更改first的值
        } else {//如果不是
            prev.next = next;//将前一个的next域赋值为x的后一个
            x.prev = null;//将x的prev域赋值为null
        }

        if (next == null) {//如果是最后一个节点
            last = prev;//更改last的值
        } else {
            next.prev = prev;//将后一个的prev域赋值为x的前一个
            x.next = null;//将x的next域赋值为null
        }

        x.item = null;//将x的item域赋值为null
        size--;//size - 1
        modCount++;//modCount + 1
        return element;//返回
    }

    //将第一个节点的item域返回
    public E getFirst() {
        final Node<E> f = first;
        if (f == null)
            throw new NoSuchElementException();
        return f.item;
    }

    //将最后一个节点的item域返回
    public E getLast() {
        final Node<E> l = last;
        if (l == null)
            throw new NoSuchElementException();
        return l.item;
    }
	
	//将第一个节点的值移除之后返回
    public E removeFirst() {
        final Node<E> f = first;
        if (f == null) 
            throw new NoSuchElementException();
        return unlinkFirst(f);//调用了{4}处定义的方法
		//作用是将第一个节点移除并返回其item域
    }

    //将最后一个节点移除并返回
    public E removeLast() {
        final Node<E> l = last;
        if (l == null)
            throw new NoSuchElementException();
        return unlinkLast(l);//同上,调用{5}处方法
    }

    //头插
    public void addFirst(E e) {
        linkFirst(e);//调用{6}
    }

    //尾插
    public void addLast(E e) {
        linkLast(e);//调用{7}
    }

    //是否包含o
    public boolean contains(Object o) {
        return indexOf(o) != -1;//调用{8}
    }

	//返回元素个数,size的存在使得本方法不必遍历,效率得到提高
    public int size() {
        return size;
    }

    //addLast改头换面版本,只不过是增加了返回值...
    public boolean add(E e) {
        linkLast(e);
        return true;
    }

    //和indexOf(Object o)方法类似,找到节点之后删除
	//注:indexOf方法在{8}处
	//将第一次出现o的节点移除
	//存在返回true,不存在返回false(应该是操作成功返回的)
    public boolean remove(Object o) {
        if (o == null) {
            for (Node<E> x = first; x != null; x = x.next) {
                if (x.item == null) {
                    unlink(x);//调用{9}
                    return true;
                }
            }
        } else {
            for (Node<E> x = first; x != null; x = x.next) {
                if (o.equals(x.item)) {
                    unlink(x);//调用{9}
                    return true;
                }
            }
        }
        return false;
    }

	//{3}
    public boolean addAll(Collection<? extends E> c) {
        return addAll(size, c);//见{10}
    }

	//{10}
    //从指定值开始插入c
    public boolean addAll(int index, Collection<? extends E> c) {
        checkPositionIndex(index);//见{11}

		//--提取c中的数据
        Object[] a = c.toArray();//将c转变成为数组
        int numNew = a.length;//新插入元素的个数
        if (numNew == 0)//如果插入元素个数为0
            return false;

		//初始化前置节点和后置节点
        Node<E> pred, succ;
        if (index == size) {//尾插
            succ = null;//后置节点为空(因为最后一个后面没有了)
            pred = last;//前驱节点为最后一个节点
        } else {
			//查找到第index个节点
            succ = node(index);//见{13}
            pred = succ.prev;
        }

        for (Object o : a) {//开始进行遍历
            @SuppressWarnings("unchecked") E e = (E) o;//暂存
            Node<E> newNode = new Node<>(pred, e, null);//创建新节点
            if (pred == null)//如果是从0开始,即index == 0或者空表
                first = newNode;//更改第一个的值
            else
                pred.next = newNode;//前一个的next域变为创建节点
            pred = newNode;//因为要从新节点开始插入,所以前置节点变成新创建的节点
        }

		//等到所有的元素都添加完毕之后
        if (succ == null) {//如果后置节点是空
            last = pred;//将尾结点置为添加的最后一个节点
        } else {//若不是尾插
            pred.next = succ;//最后一个节点的next域赋值为后置节点
            succ.prev = pred;//后置节点的prev域赋值为最后一个插入的节点
        }

        size += numNew;//容量增加
        modCount++;//其实我觉得modCount应该加上numNew
        return true;//返回操作成功
    }

    
    public void clear() {
		//用于触发gc
        for (Node<E> x = first; x != null; ) {
            Node<E> next = x.next;
            x.item = null;
            x.next = null;
            x.prev = null;
            x = next;
        }
		//之后才是正经的删除代码
        first = last = null;
        size = 0;
        modCount++;
    }


	// 指定位置访问
    // Positional Access Operations

    //喜闻乐见的get方法
    public E get(int index) {
        checkElementIndex(index);//见{14}
		//下标检查
        return node(index).item;//查询之后返回
    }

    public E set(int index, E element) {
        checkElementIndex(index);//下标检查
        Node<E> x = node(index);//查询
        E oldVal = x.item;//暂存旧值
        x.item = element;//赋新值
        return oldVal;//返回旧值
    }

    public void add(int index, E element) {
        checkPositionIndex(index);//下标检查
		//要求0-size

        if (index == size)//如果是尾插
            linkLast(element);//调用尾插
        else//一般插入
            linkBefore(element, node(index));
			//在这个节点之前插入,作为第index个节点
    }

	//将指定位置的删除
    public E remove(int index) {
        checkElementIndex(index);//下标检查
        return unlink(node(index));//将index的节点删除
    }

	//{15}
    //下标对应的值在list中是否存在
    private boolean isElementIndex(int index) {
        return index >= 0 && index < size;
    }

    //告知我们这个下标是否对于迭代器和添加操作是安全的
    private boolean isPositionIndex(int index) {
        return index >= 0 && index <= size;
    }

    //返回一个信息
    private String outOfBoundsMsg(int index) {
        return "Index: "+index+", Size: "+size;
    }

	//{14}
	//一个检查方法
    private void checkElementIndex(int index) {
        if (!isElementIndex(index))//见{15}
            throw new IndexOutOfBoundsException(outOfBoundsMsg(index));
    }

	//{11}
	//emmm一个下标检查方法
    private void checkPositionIndex(int index) {
        if (!isPositionIndex(index))//见{12}
		//检查下标是否对于迭代器和添加操作是有效的
            throw new IndexOutOfBoundsException(outOfBoundsMsg(index));
    }

	//{13}
    //实际上相当于一个内部的get方法
    Node<E> node(int index) {
        if (index < (size >> 1)) {//如果index比较靠前
            Node<E> x = first;//从前向后进行查找
            for (int i = 0; i < index; i++)
                x = x.next;
            return x;
        } else {
            Node<E> x = last;//如果index比较靠后,从后向前进行查找
            for (int i = size - 1; i > index; i--)
                x = x.prev;
            return x;//返回顺序查找的结果
        }
    }

    // Search Operations

    //返回o第一次出现的下标{8}
    public int indexOf(Object o) {
        int index = 0;//从0开始
		//之后的判断是不是似曾相识?
		//哈哈~在ArrayList中就是这么处理的~
        if (o == null) {
            for (Node<E> x = first; x != null; x = x.next, /*index ++*/) {
				//元素从0个开始,下标也是从0开始。
                if (x.item == null)
                    return index;
                index++;
            }
        } else {
            for (Node<E> x = first; x != null; x = x.next) {
                if (o.equals(x.item))
                    return index;
                index++;
            }
        }
        return -1;
    }

    //返回最后一个出现o的下标
    public int lastIndexOf(Object o) {
        int index = size;
        if (o == null) {//同ArrayList中的控制,避免空指针异常
            for (Node<E> x = last; x != null; x = x.prev) {
                index--;
                if (x.item == null)
                    return index;
            }
        } else {
            for (Node<E> x = last; x != null; x = x.prev) {
                index--;
                if (o.equals(x.item))
                    return index;
            }
        }
        return -1;
    }

	//队列操作
    // Queue operations.
    //将第一个元素返回
    public E peek() {
        final Node<E> f = first;
        return (f == null) ? null : f.item;//空指针
    }

	//和上面不同的是,如果链表是空的,将会抛出NoSuchElementException
    public E element() {
        return getFirst();
    }

    //第一个返回并删除
    public E poll() {
        final Node<E> f = first;
        return (f == null) ? null : unlinkFirst(f);
    }

    //和element方法差不多,没有元素抛出异常
    public E remove() {
        return removeFirst();
    }

    //不解释
    public boolean offer(E e) {
        return add(e);
    }

    // Deque operations
    //头插
    public boolean offerFirst(E e) {
        addFirst(e);
        return true;
    }

    //头插
    public boolean offerLast(E e) {
        addLast(e);
        return true;
    }

    //返回第一个
    public E peekFirst() {
        final Node<E> f = first;
        return (f == null) ? null : f.item;
     }

    //返回最后一个
    public E peekLast() {
        final Node<E> l = last;
        return (l == null) ? null : l.item;
    }

    //第一个返回并移除
    public E pollFirst() {
        final Node<E> f = first;
        return (f == null) ? null : unlinkFirst(f);
    }

    //返回最后一个并移除
    public E pollLast() {
        final Node<E> l = last;
        return (l == null) ? null : unlinkLast(l);
    }

    //头插
    public void push(E e) {
        addFirst(e);
    }

    //尾删
    public E pop() {
        return removeFirst();
    }

    //给定值操作,值删
    public boolean removeFirstOccurrence(Object o) {
        return remove(o);
    }

    //同上,只不过删除的是左后一个
    public boolean removeLastOccurrence(Object o) {
        if (o == null) {
            for (Node<E> x = last; x != null; x = x.prev) {
                if (x.item == null) {
                    unlink(x);
                    return true;
                }
            }
        } else {
            for (Node<E> x = last; x != null; x = x.prev) {
                if (o.equals(x.item)) {
                    unlink(x);
                    return true;
                }
            }
        }
        return false;
    }

    /*
	和ArrayList一样,都是在接口中给出定义,
	之后在具体实现的数据结构的内部类中给出实现。
	*/
    public ListIterator<E> listIterator(int index) {
        checkPositionIndex(index);//下标检查
        return new ListItr(index);
    }

    private class ListItr implements ListIterator<E> {
        private Node<E> lastReturned;//刚刚返回的节点(或者说是将要进行操作的节点)
        private Node<E> next;//将要返回的节点
        private int nextIndex;//将要返回的节点的下标
        private int expectedModCount = modCount;//期望的modCount值

        ListItr(int index) {//构造方法
            next = (index == size) ? null : node(index);
			//如果不加上上面的而一句,index = size的情况就覆盖不到
            nextIndex = index;//下一个将要返回的下标定为index
        }

        public boolean hasNext() {//是否有下一个
            return nextIndex < size;
        }

        public E next() {//将当前next指向的节点返回
            checkForComodification();//检查list是否进行了结构化更改
            if (!hasNext())//有没有下一个,实则相当于下标检查(内部类中的下标检查)
                throw new NoSuchElementException();

			//这几句就没有什么好说的了
            lastReturned = next;//将表示刚刚返回的lastReturned赋值为next
            next = next.next;
            nextIndex++;
            return lastReturned.item;
        }

        public boolean hasPrevious() {//返回是否有前驱节点
            return nextIndex > 0;//感觉用 next.prev != null 也行
        }

        public E previous() {//返回前一个
            checkForComodification();//更改检查
            if (!hasPrevious())//是否有前一个
                throw new NoSuchElementException();

			/*这里首先考虑next的取值,next可能由于遍历了list而指向了最后一个的后一个*/
            lastReturned = next = (next == null) ? last : next.prev;//避免空指针异常
            nextIndex--;
            return lastReturned.item;
        }

        public int nextIndex() {//将即将要操作元素的下标返回
            return nextIndex;
        }

        public int previousIndex() {//将即将要操作的元素的前驱节点的下标返回
            return nextIndex - 1;
        }

        public void remove() {//删除
            checkForComodification();//修改检查
            if (lastReturned == null)//如果之前返回的是null
                throw new IllegalStateException();
				//不允许创建之后没有进行任何返回就开始修改表?

            Node<E> lastNext = lastReturned.next;//上一次返回的下一个暂存
            unlink(lastReturned);//将上一次返回的节点删除
			if (next == lastReturned)
				//如果将要进行操作的节点和上一次返回的节点一样的话
				//这种情况主要针对之前调用了previous方法的情况
                next = lastNext;//将要操作的节点赋值成为删除节点的下一个
            else//这种就是一般的调用了next方法的
                nextIndex--;如果不是,就将下标进行改变
            lastReturned = null;//最后一次返回的值置为空
			//因为这个节点不能删两次(实际上删除的永远应该是已经遍历或者说是访问到的节点)
            expectedModCount++;//将期望的modCount + 1
        }

        public void set(E e) {//
            if (lastReturned == null)//如果刚刚经历过删除或者Iterator刚刚进行创建
                throw new IllegalStateException();
            checkForComodification();//修改检查
            lastReturned.item = e;//刚刚的返回节点进行修改
        }

        public void add(E e) {//添加
            checkForComodification();//修改检查
            lastReturned = null;
            if (next == null)//如果遍历到了最后一个
                linkLast(e);//尾插
            else
                linkBefore(e, next);//在下一个之前插入
            nextIndex++;//下一个的下标+1
            expectedModCount++;//修改modCount
        }

		//和ArrayList中相同,都是对于每一个值进行同样的操作
		//确切的说,是对于还没有访问过的值进行已经定义的相同操作
        public void forEachRemaining(Consumer<? super E> action) {
            Objects.requireNonNull(action);//判空
            while (modCount == expectedModCount && nextIndex < size) {
                action.accept(next.item);//进行操作
                lastReturned = next;//相当于遍历,修改lastReturned的值
                next = next.next;//将next的值改变
                nextIndex++;//nextIndex值修改
            }
            checkForComodification();//检查修改
        }

		//检查修改方法
        final void checkForComodification() {
            if (modCount != expectedModCount)
                throw new ConcurrentModificationException();
        }
    }

	//这里可以看到Node的定义
	//双节点
    private static class Node<E> {
        E item;
        Node<E> next;
        Node<E> prev;

        Node(Node<E> prev, E element, Node<E> next) {
            this.item = element;
            this.next = next;
            this.prev = prev;
        }
    }

    /**
     * @since 1.6
     */
	 //从1.6就开始有的一个类
	 //用于从另一个方向遍历
    public Iterator<E> descendingIterator() {
        return new DescendingIterator();
    }

    //倒序Iterator
	//相对于之前Itr的实现,挺有意思的
    private class DescendingIterator implements Iterator<E> {
        private final ListItr itr = new ListItr(size());
        public boolean hasNext() {
            return itr.hasPrevious();
        }
        public E next() {
            return itr.previous();
        }
        public void remove() {
            itr.remove();
        }
    }

	//克隆方法
    @SuppressWarnings("unchecked")
    private LinkedList<E> superClone() {
        try {
            return (LinkedList<E>) super.clone();
        } catch (CloneNotSupportedException e) {
            throw new InternalError(e);
        }
    }

	//浅克隆
    public Object clone() {
        LinkedList<E> clone = superClone();

        // Put clone into "virgin" state
        clone.first = clone.last = null;
        clone.size = 0;
        clone.modCount = 0;

        //如果你好奇为什么first并没有初始化,看看add方法中做了什么就知道了
        for (Node<E> x = first; x != null; x = x.next)
            clone.add(x.item);

        return clone;
    }

    //转化成为数组
    public Object[] toArray() {
        Object[] result = new Object[size];
        int i = 0;
        for (Node<E> x = first; x != null; x = x.next)
            result[i++] = x.item;
        return result;
    }

	//
    @SuppressWarnings("unchecked")
    public <T> T[] toArray(T[] a) {
        if (a.length < size)//如果a的长度比较小,创建一个新的数组
            a = (T[])java.lang.reflect.Array.newInstance(
                                a.getClass().getComponentType(), size);
        int i = 0;//将i的值置为0
        Object[] result = a;
		//复制
        for (Node<E> x = first; x != null; x = x.next)
            result[i++] = x.item;

        if (a.length > size)//用于判断长度用的
            a[size] = null;

        return a;//返回结果
    }

	//好神奇的位置...
    private static final long serialVersionUID = 876323262645176354L;

    //就是...将他存起来
    private void writeObject(java.io.ObjectOutputStream s)
        throws java.io.IOException {
		//将类中除了static和transient修饰的变量存起来
		//只能在writeObject中调用
        s.defaultWriteObject();
		
        //你懂得
        s.writeInt(size);

        //依旧是只存元素
        for (Node<E> x = first; x != null; x = x.next)
            s.writeObject(x.item);
    }

    //读
    @SuppressWarnings("unchecked")
    private void readObject(java.io.ObjectInputStream s)
        throws java.io.IOException, ClassNotFoundException {
        //和上面的正好的反过来的,不多解释了
        s.defaultReadObject();

        // Read in size
        int size = s.readInt();

        // Read in all elements in the proper order.
        for (int i = 0; i < size; i++)
            linkLast((E)s.readObject());
    }

    //可分割的Iterator
    @Override
    public Spliterator<E> spliterator() {
        return new LLSpliterator<E>(this, -1, 0);
    }

    //并行迭代器
    static final class LLSpliterator<E> implements Spliterator<E> {
        static final int BATCH_UNIT = 1 << 10;  //一批增长的大小
        static final int MAX_BATCH = 1 << 25;  //一批增长的最大大小
        final LinkedList<E> list; //迭代对象
        Node<E> current;      //当前节点
        int est;              //估算大小(你当成实际的看也行)
        int expectedModCount; //期望的修改值
        int batch;            //一批增长的粒度

        LLSpliterator(LinkedList<E> list, int est, int expectedModCount) {
            this.list = list;
            this.est = est;
            this.expectedModCount = expectedModCount;
        }

		//初始化current、expectedModCount和est并返回est
        final int getEst() {
            int s; // force initialization(需要我们强制指定?)
            final LinkedList<E> lst;
            if ((s = est) < 0) {//如果est小于0(没有调用过这个方法)
                if ((lst = list) == null)//如果传入list为空
                    s = est = 0;
                else {//如果list不为空
                    expectedModCount = lst.modCount;//初始化
                    current = lst.first;//初始化
                    s = est = lst.size;
                }
            }
            return s;
        }

		//估算大小
        public long estimateSize() { return (long) getEst(); }

		//分割出来之后是基于数组的...反正都能用是吧
        public Spliterator<E> trySplit() {
            Node<E> p;
            int s = getEst();//得到估算大小
            if (s > 1 && (p = current) != null) {//current是第一个节点,证明当前值不为空
                int n = batch + BATCH_UNIT;
                if (n > s)
                    n = s;
                if (n > MAX_BATCH)
                    n = MAX_BATCH;
				//计算分割上限
                Object[] a = new Object[n];
                int j = 0;
                do { a[j++] = p.item; } while ((p = p.next) != null && j < n);
                current = p;
                batch = j;
                est = s - j;
                return Spliterators.spliterator(a, 0, j, Spliterator.ORDERED);
            }
            return null;
        }

		//执行指定操作
        public void forEachRemaining(Consumer<? super E> action) {
            Node<E> p; int n;
            if (action == null) throw new NullPointerException();
            if ((n = getEst()) > 0 && (p = current) != null) {
                current = null;
                est = 0;
                do {
                    E e = p.item;
                    p = p.next;
                    action.accept(e);
                } while (p != null && --n > 0);
            }
            if (list.modCount != expectedModCount)
                throw new ConcurrentModificationException();
        }

		//处理一个(就像Iterator修改一样)
        public boolean tryAdvance(Consumer<? super E> action) {
            Node<E> p;
            if (action == null) throw new NullPointerException();
            if (getEst() > 0 && (p = current) != null) {
                --est;
                E e = p.item;
                current = p.next;
                action.accept(e);
                if (list.modCount != expectedModCount)
                    throw new ConcurrentModificationException();
                return true;
            }
            return false;
        }

		//返回特征值
        public int characteristics() {
            return Spliterator.ORDERED | Spliterator.SIZED | Spliterator.SUBSIZED;
        }
    }

}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值