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

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

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

         ArrayList<String> list = new ArrayList<String>();         
         list.add(null);
         list.add("abc1");
         list.add("abc2");
         list.add("abc3");
         list.add("abc4");
         /*
          * 使用迭代器遍历集合
          */
         //获取迭代器
        Iterator<String> 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<String> 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 TypeMethod and Description
voidforEach(Consumer<? super E> action)

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

Iterator<E>iterator()

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

ListIterator<E>listIterator()

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

ListIterator<E>listIterator(int index)

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

package java.util;

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

public class ArrayList<E> extends AbstractList<E>
        implements List<E>, 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<? extends E> 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<E> listIterator(int index) {
        if (index < 0 || index > size)
            throw new IndexOutOfBoundsException("Index: "+index);
        return new ListItr(index);
    }

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

    public Iterator<E> iterator() {
        return new Itr();
    }

    private class Itr implements Iterator<E> {
        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<? super E> 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<E> {
        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<E>一个集合的迭代器。 Iterator需要的地方Enumeration在Java集合框架。 迭代器有两种不同的枚举方式:
迭代器允许调用者在迭代期间从底层集合中删除元素,并具有明确定义的语义。 
方法名称得到改进。 
此接口是成员Java Collections Framework 。 

Modifier and TypeMethod and Description
default voidforEachRemaining(Consumer<? super E> action)

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

booleanhasNext()

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

Enext()

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

default voidremove()

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

package java.util;

import java.util.function.Consumer;

public interface Iterator<E> {

    boolean hasNext();

    E next();


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

    default void forEachRemaining(Consumer<? super E> 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 TypeMethod and Description
voidadd(E e)

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

booleanhasNext()

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

booleanhasPrevious()

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

Enext()

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

intnextIndex()

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

Eprevious()

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

intpreviousIndex()

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

voidremove()

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

voidset(E e)

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

package java.util;

public interface ListIterator<E> extends Iterator<E> {
    // 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);
}

 

 

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

wespten

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值