java基础之Iterator和Iterable

一、5种循环方式

  • do...while
  • while
  • for
  • iterator
  • 增强for循环
ArrayList list=new ArrayList();
list.add(1);
list.add(2);
list.add(3);
list.add(4);
//for循环
for(int i=0;i

二、Iterator和Iterable

1.区别和联系:

  • 所有的集合类都默认实现了Iterable的接口 。Iterable接口中的方法: iterator() ,foreach() 。
  • Iterator 也是一个接口,是由Iterable接口中的 iterator()返回。Iterator接口中的方法:hasNext()和next()。
  • 迭代器Iterator 为集合而生,专门实现集合遍历

2.使用Iterator遍历的本质是实现Iterable接口 。

3.Iterator中hasNext()和next()的实现原理

java基础之Iterator和Iterable_第1张图片

//hasNext()和next()的实现原理
int cursor;       // index of next element to return
int lastRet = -1;

public boolean hasNext() {
    return cursor != size;//size:集合的大小
}

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];
}
——————————————————————————————————————————————————————————————————————————
//调用
Iterator iterator = list.iterator();
while(iterator.hasNext()){
    System.out.println(iterator.next());
}

 4.在遍历过程中不能使用集合删除元素,应使用迭代器删除

使用list,直接删除元素,将会报“ConcurrentModificationException”异常。

ArrayList list=new ArrayList();
list.add(1);
list.add(2);
list.add(3);
list.add(4);

Iterator iterator = list.iterator();
while(iterator.hasNext()){
    Object o=iterator.next();
    if(o.equals(2)){
        list.remove(o);//ConcurrentModificationException 并发修改异常
    }
    System.out.print(o+"\t");
}
System.out.println();
for(Object i:list){
    System.out.print(i+"\t");
}
--------------------------------------------------------------------------
输出结果:
D:\program\javatotal\JDK\JDK12\jdk-12.0.2\bin\java.exe "-javaagent:D:\program\MyIdea\AZ\IntelliJ IDEA 2019.2.2\lib\idea_rt.jar=1793:D:\program\MyIdea\AZ\IntelliJ IDEA 2019.2.2\bin" -Dfile.encoding=UTF-8 -classpath D:\Programs\IdeaProjects\CommonClass\out\production\CommonClass Collection.InteratorDemo
1	2	Exception in thread "main" java.util.ConcurrentModificationException
	at java.base/java.util.ArrayList$Itr.checkForComodification(ArrayList.java:1042)
	at java.base/java.util.ArrayList$Itr.next(ArrayList.java:996)
	at Collection.InteratorDemo.main(InteratorDemo.java:15)

java基础之Iterator和Iterable_第2张图片

使用ListIterator进行删除元素

ArrayList list=new ArrayList();
list.add(1);
list.add(2);
list.add(3);
list.add(4);

ListIterator iterator = list.listIterator();
while(iterator.hasNext()){
    Object o=iterator.next();
    if(o.equals(2)){
        iterator.remove();
    }
    System.out.print(o+"\t");
}
System.out.println();
for(Object i:list){
    System.out.print(i+"\t");
}
-------------------------------------------
输出结果:
1	2	3	4	
1	3	4

ListIterator是个接口,有个remove()抽象方法,该方法由ArrayList类的内部类Itr中的方法remove()实现。具体方法如下:

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();
    }
}

java基础之Iterator和Iterable_第3张图片

总结:

1.如果想要在迭代的过程中进行向集合中添加,修改元素等就需要使用ListIterator接口中的方法,因为Iterator接口中,没有add方法。

2.不能直接对ArrayList进行删除操作,因为,Iterator有两个指向ArrayList数组的指针,当ArrayList执行remove操作时,相当于,之后的元素都向前进行移动,那么cursor和lastRet两个指针执行的内容就会发生错误。

5.使用ListIterator 向前遍历和向后遍历

ArrayList list=new ArrayList();
list.add(1);
list.add(2);
list.add(3);
list.add(4);

//向后遍历
ListIterator iterator = list.listIterator();
while(iterator.hasNext()){
    System.out.print(iterator.next()+"\t");
}
System.out.println();

//向前遍历
while(iterator.hasPrevious()){
    System.out.print(iterator.previous()+"\t");
}
-------------------------------------------
输出结果:
1	2	3	4	
4	3	2	1	
———————————————————————————————————————————

注意:
1.当向后遍历时,指针移到了最后一位,所以接着向前遍历时,就倒序遍历了一遍。
2.当使用向前遍历的事后必须要保证指针在迭代器的结尾,否则无法获取结果值。 

三、增强for循环

1.优点:

  • 增强的for循环,遍历array或Collection的时候相当简便 。
  • 无需获得集合和数组的长度,无需使用索引访问元素,无需循环条件。

2.缺点:

  • 对于数组 ,不能方便的访问下标值 ;不要在for-each中尝试对变量赋值,只是一个临时变量。
  • 对于集合,和使用Iterator相比,不能方便的删除集合中的内容 。遍历集合时底层调用Iterator完成操作。

3.除了简单的遍历并读出其中的内容外,不建议使用增强for

 

 

 

你可能感兴趣的:(java学习)