深入学习java源码之ArrayList.iterator()与ArrayList.listIterator()

深入学习java源码之ArrayList.iterator()与ArrayList.listIterator()

内部类的使用典型的情况是,内部类继承自某个类或实现某个接口,内部类的代码操作创建其的外层类的对象。所以你可以认为内部类提供了某种进入其外层类的窗口。
    使用内部类最吸引人的原因是:每个内部类都能独立地继承自一个(接口的)实现,所以无论外层类是否已经继承了某个(接口的)实现,对于内部类都没有影响。如果没有内部类提供的可以继承多个具体的或抽象的类的能力,一些设计与编程问题就很难解决。从这个角度看,内部类使得多重继承的解决方案变得完整。接口解决了部分问题,而内部类有效地实现了“多重继承”。

         ArrayList list = new ArrayList();         
         list.add(null);
         list.add("abc1");
         list.add("abc2");
         list.add("abc3");
         list.add("abc4");
         /*
          * 使用迭代器遍历集合
          */
         //获取迭代器
        Iterator it = list.iterator();
         //使用while遍历集合
        while(it.hasNext()){
             String s = it.next();             
             /*
              * 判断集合中有没有"abc3"这个元素
              * 如果有,增加一个元素"itcast"
              * 编程技巧:使用equals判断的时候,要把已知的变量写在前边,未知的写在后边,防止空指针异常
              */
             //if(s.equals("abc3")){
             if("abc3".equals(s)){
                 //1.迭代就是迭代,不要对集合进行修改
                 //list.add("itcast");
             }             
             System.out.println(s);
         }         
        
         /*
          * 2.使用迭代器Iterator的子接口ListIterator中的方法add/remove,让迭代器自己增加往集合中增加元素/移除元素
          */
         ListIterator listIt = list.listIterator();
         while(listIt.hasNext()){
             String s = listIt.next();
             if("abc3".equals(s)){
                 listIt.add("itcast");
             }
             System.out.println(s);
         }
         System.out.println(list);
     }

集合类(包括List)现在都有一个forEach方法,对元素进行迭代(遍历),所以我们不需要再写for循环了。forEach方法接受一个函数接口Consumer做参数,所以可以使用λ表达式。
这种内部迭代方法广泛存在于各种语言,如C++的STL算法库、python、ruby、scala等。

    for(Object o: list) { // 外部迭代
        System.out.println(o);
    }

可以写成:

    list.forEach(o -> {System.out.println(o);}); //forEach函数实现内部迭代

 

 

java源码

一个集合的迭代器。 Iterator需要的地方Enumeration在Java集合框架。 迭代器有两种不同的枚举方式: 
迭代器允许调用者在迭代期间从底层集合中删除元素,并具有明确定义的语义。 
方法名称得到改进。

Modifier and Type Method and Description
void forEach(Consumer action)

Iterable的每个元素执行给定的操作,直到所有元素都被处理或动作引发异常。

Iterator iterator()

以正确的顺序返回该列表中的元素的迭代器。

ListIterator listIterator()

返回列表中的列表迭代器(按适当的顺序)。

ListIterator listIterator(int index)

从列表中的指定位置开始,返回列表中的元素(按正确顺序)的列表迭代器。

package java.util;

import java.util.function.Consumer;
import java.util.function.Predicate;
import java.util.function.UnaryOperator;

public class ArrayList extends AbstractList
        implements List, RandomAccess, Cloneable, java.io.Serializable
{
    private static final long serialVersionUID = 8683452581122892189L;

    private static final int DEFAULT_CAPACITY = 10;

    private static final Object[] EMPTY_ELEMENTDATA = {};

    private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {};

    transient Object[] elementData; // non-private to simplify nested class access

    private int size;

    public ArrayList(int initialCapacity) {
        if (initialCapacity > 0) {
            this.elementData = new Object[initialCapacity];
        } else if (initialCapacity == 0) {
            this.elementData = EMPTY_ELEMENTDATA;
        } else {
            throw new IllegalArgumentException("Illegal Capacity: "+
                                               initialCapacity);
        }
    }

    public ArrayList() {
        this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA;
    }

    public ArrayList(Collection c) {
        elementData = c.toArray();
        if ((size = elementData.length) != 0) {
            // c.toArray might (incorrectly) not return Object[] (see 6260652)
            if (elementData.getClass() != Object[].class)
                elementData = Arrays.copyOf(elementData, size, Object[].class);
        } else {
            // replace with empty array.
            this.elementData = EMPTY_ELEMENTDATA;
        }
    }

    public ListIterator listIterator(int index) {
        if (index < 0 || index > size)
            throw new IndexOutOfBoundsException("Index: "+index);
        return new ListItr(index);
    }

    public ListIterator listIterator() {
        return new ListItr(0);
    }

    public Iterator iterator() {
        return new Itr();
    }

    private class Itr implements Iterator {
        int cursor;       // index of next element to return
        int lastRet = -1; // index of last element returned; -1 if no such
        int expectedModCount = modCount;

        public boolean hasNext() {
            return cursor != size;
        }

        @SuppressWarnings("unchecked")
        public E next() {
            checkForComodification();
            int i = cursor;
            if (i >= size)
                throw new NoSuchElementException();
            Object[] elementData = ArrayList.this.elementData;
            if (i >= elementData.length)
                throw new ConcurrentModificationException();
            cursor = i + 1;
            return (E) elementData[lastRet = i];
        }

        public void remove() {
            if (lastRet < 0)
                throw new IllegalStateException();
            checkForComodification();

            try {
                ArrayList.this.remove(lastRet);
                cursor = lastRet;
                lastRet = -1;
                expectedModCount = modCount;
            } catch (IndexOutOfBoundsException ex) {
                throw new ConcurrentModificationException();
            }
        }

        @Override
        @SuppressWarnings("unchecked")
        public void forEachRemaining(Consumer consumer) {
            Objects.requireNonNull(consumer);
            final int size = ArrayList.this.size;
            int i = cursor;
            if (i >= size) {
                return;
            }
            final Object[] elementData = ArrayList.this.elementData;
            if (i >= elementData.length) {
                throw new ConcurrentModificationException();
            }
            while (i != size && modCount == expectedModCount) {
                consumer.accept((E) elementData[i++]);
            }
            // update once at end of iteration to reduce heap write traffic
            cursor = i;
            lastRet = i - 1;
            checkForComodification();
        }

        final void checkForComodification() {
            if (modCount != expectedModCount)
                throw new ConcurrentModificationException();
        }
    }

    private class ListItr extends Itr implements ListIterator {
        ListItr(int index) {
            super();
            cursor = index;
        }

        public boolean hasPrevious() {
            return cursor != 0;
        }

        public int nextIndex() {
            return cursor;
        }

        public int previousIndex() {
            return cursor - 1;
        }

        @SuppressWarnings("unchecked")
        public E previous() {
            checkForComodification();
            int i = cursor - 1;
            if (i < 0)
                throw new NoSuchElementException();
            Object[] elementData = ArrayList.this.elementData;
            if (i >= elementData.length)
                throw new ConcurrentModificationException();
            cursor = i;
            return (E) elementData[lastRet = i];
        }

        public void set(E e) {
            if (lastRet < 0)
                throw new IllegalStateException();
            checkForComodification();

            try {
                ArrayList.this.set(lastRet, e);
            } catch (IndexOutOfBoundsException ex) {
                throw new ConcurrentModificationException();
            }
        }

        public void add(E e) {
            checkForComodification();

            try {
                int i = cursor;
                ArrayList.this.add(i, e);
                cursor = i + 1;
                lastRet = -1;
                expectedModCount = modCount;
            } catch (IndexOutOfBoundsException ex) {
                throw new ConcurrentModificationException();
            }
        }
    }
}

 ConcurrentModificationException 异常

当不允许这样的修改时,可以通过检测到对象的并发修改的方法来抛出此异常。 
例如,一个线程通常不允许修改集合,而另一个线程正在遍历它。 一般来说,在这种情况下,迭代的结果是未定义的。 某些迭代器实现(包括由JRE提供的所有通用集合实现的实现)可能会选择在检测到此行为时抛出此异常。 这样做的迭代器被称为故障快速迭代器,因为它们快速而干净地失败,而是在未来未确定的时间冒着任意的非确定性行为。 

请注意,此异常并不总是表示对象已被不同的线程同时修改。 如果单个线程发出违反对象合同的方法调用序列,则该对象可能会抛出此异常。 例如,如果线程在使用故障快速迭代器迭代集合时直接修改集合,则迭代器将抛出此异常。 

请注意,故障快速行为无法保证,因为一般来说,在不同步并发修改的情况下,无法做出任何硬性保证。 失败快速的操作尽可能地抛出ConcurrentModificationException 。 因此,编写依赖于此异常的程序的正确性将是错误的: ConcurrentModificationException应仅用于检测错误。 

package java.util;

public class ConcurrentModificationException extends RuntimeException {
    private static final long serialVersionUID = -3666751008965953603L;

    public ConcurrentModificationException() {
    }

    public ConcurrentModificationException(String message) {
        super(message);
    }

    public ConcurrentModificationException(Throwable cause) {
        super(cause);
    }

    public ConcurrentModificationException(String message, Throwable cause) {
        super(message, cause);
    }
}

Iterator

public interface Iterator一个集合的迭代器。 Iterator需要的地方Enumeration在Java集合框架。 迭代器有两种不同的枚举方式:
迭代器允许调用者在迭代期间从底层集合中删除元素,并具有明确定义的语义。 
方法名称得到改进。 
此接口是成员Java Collections Framework 。 

Modifier and Type Method and Description
default void forEachRemaining(Consumer action)

对每个剩余元素执行给定的操作,直到所有元素都被处理或动作引发异常。

boolean hasNext()

如果迭代具有更多元素,则返回 true

E next()

返回迭代中的下一个元素。

default void remove()

从底层集合中删除此迭代器返回的最后一个元素(可选操作)。

package java.util;

import java.util.function.Consumer;

public interface Iterator {

    boolean hasNext();

    E next();


    default void remove() {
        throw new UnsupportedOperationException("remove");
    }

    default void forEachRemaining(Consumer action) {
        Objects.requireNonNull(action);
        while (hasNext())
            action.accept(next());
    }
}

ListIterator

用于允许程序员沿任一方向遍历列表的列表的迭代器,在迭代期间修改列表,并获取列表中迭代器的当前位置。 A ListIterator没有电流元素; 其光标位置始终位于通过调用previous()返回的元素和通过调用next()返回的元素next() 。 长度为n的列表的迭代器具有n+1可能的光标位置,如下图所示的^ ( ^ )所示: 
  Element(0)   Element(1)   Element(2)   ... Element(n-1)
 cursor positions:  ^            ^            ^            ^                  ^ 请注意, remove()和set(Object)方法未按光标位置进行定义; 它们被定义为对调用next()或previous()返回的最后一个元素进行操作。 

Modifier and Type Method and Description
void add(E e)

将指定的元素插入列表(可选操作)。

boolean hasNext()

返回 true如果遍历正向列表,列表迭代器有多个元素。

boolean hasPrevious()

返回 true如果遍历反向列表,列表迭代器有多个元素。

E next()

返回列表中的下一个元素,并且前进光标位置。

int nextIndex()

返回随后调用 next()返回的元素的索引。

E previous()

返回列表中的上一个元素,并向后移动光标位置。

int previousIndex()

返回由后续调用 previous()返回的元素的索引。

void remove()

从列表中删除由 next()previous()返回的最后一个元素(可选操作)。

void set(E e)

用 指定的元素替换由 next()previous()返回的最后一个元素(可选操作)。

package java.util;

public interface ListIterator extends Iterator {
    // Query Operations

    boolean hasNext();

    E next();

    boolean hasPrevious();

    E previous();

    int nextIndex();

    int previousIndex();


    // Modification Operations

    void remove();

    void set(E e);

    void add(E e);
}

 

 

你可能感兴趣的:(Java源码)