迭代器
- 含义:遍历集合中的数据
- 分类:Iterator 和 ListIterator
- Iterator 和 ListIterator 区别
Iterator :Collection接口下所有的实现类都可以获取的迭代器,可以在遍历时删除元素
ListIterator :List接口下所有的实现类可以获取的迭代器,可以在遍历时删除、替换、添加元素,也可以指定下标开始遍历,还可以倒叙遍历
1 迭代器深入
1.1 深入迭代器-foreach
public class Test01 {
/**
* 知识点:深入迭代器 -- foreach
*/
public static void main(String[] args) {
ArrayList<String> list = new ArrayList<>();
list.add("aaa");
list.add("bbb");
list.add("ccc");
list.add("ddd");
list.add("eee");
for (String element : list) {
System.out.println(element);
}
/**
* 使用foreach循环遍历集合的底层实现:
* String element;
for(Iterator it = list.iterator();it.hasNext();System.out.println(element))
element = (String) it.next();
*/
}
}
1.2 深入迭代器 – Iterator
1.2.1 需求:Iterator如何遍历元素
public class Test02 {
/**
* 知识点:深入迭代器 -- Iterator
*
* 深入:Iterator如何遍历元素
*/
public static void main(String[] args) {
ArrayList<String> list = new ArrayList<>();
list.add("aaa");
list.add("bbb");
list.add("ccc");
list.add("ddd");
list.add("eee");
list.remove("bbb");
// Iterator<String> it = list.iterator();
// while(it.hasNext()){
// String element = it.next();
// System.out.println(element);
// }
//
String element;
for(Iterator<String> it = list.iterator();it.hasNext();System.out.println(element)){
element = it.next();
}
}
}
1.2.2 使用Iterator遍历元素,遍历到"bbb"时删除该元素
public class Test03 {
/**
* 知识点:深入迭代器 -- Iterator
*
* 需求:使用Iterator遍历元素,遍历到"bbb"时删除该元素
*/
public static void main(String[] args) {
ArrayList<String> list = new ArrayList<>();
list.add("aaa");
list.add("bbb");
list.add("ccc");
list.add("ddd");
list.add("eee");
//modCount - 5
//expectedModCount - 5
Iterator<String> it = list.iterator();
while(it.hasNext()){
String element = it.next();
if(element.equals("bbb")){
//list.remove(element);//modCount - 6
it.remove();
}
}
for (String element : list) {
System.out.println(element);
}
}
}
1.3 深入迭代器 – ListIterator
1.3.1 使用ListIterator遍历元素
public class Test04 {
/**
* 知识点:深入迭代器 -- ListIterator
*
* 需求:使用ListIterator遍历元素
*/
public static void main(String[] args) {
ArrayList<String> list = new ArrayList<>();
list.add("aaa");
list.add("bbb");
list.add("ccc");
list.add("ddd");
list.add("eee");
ListIterator<String> listIterator = list.listIterator();
while(listIterator.hasNext()){
String element = listIterator.next();
System.out.println(element);
}
}
}
1.3.2 需求:使用ListIterator遍历元素,遍历到"bbb"时删除
public class Test05 {
/**
* 知识点:深入迭代器 -- ListIterator
*
* 需求:使用ListIterator遍历元素,遍历到"bbb"时删除
*/
public static void main(String[] args) {
ArrayList<String> list = new ArrayList<>();
list.add("aaa");
list.add("bbb");
list.add("ccc");
list.add("ddd");
list.add("eee");
ListIterator<String> listIterator = list.listIterator();
while(listIterator.hasNext()){
String element = listIterator.next();
if(element.equals("bbb")){
listIterator.remove();
}
}
for (String element : list) {
System.out.println(element);
}
}
}
1.3.3 需求:使用ListIterator遍历元素,遍历到"bbb"时添加"xyz"
public class Test06 {
/**
* 知识点:深入迭代器 -- ListIterator
*
* 需求:使用ListIterator遍历元素,遍历到"bbb"时添加"xyz"
*/
public static void main(String[] args) {
ArrayList<String> list = new ArrayList<>();
list.add("aaa");
list.add("bbb");
list.add("ccc");
list.add("ddd");
list.add("eee");
ListIterator<String> listIterator = list.listIterator();
while(listIterator.hasNext()){
String element = listIterator.next();
if(element.equals("bbb")){
listIterator.add("xyz");
}
}
for (String element : list) {
System.out.println(element);
}
}
}
1.3.4 需求:使用ListIterator遍历元素,遍历到"bbb"时替换成"xyz"
public class Test07 {
/**
* 知识点:深入迭代器 -- ListIterator
*
* 需求:使用ListIterator遍历元素,遍历到"bbb"时替换成"xyz"
*/
public static void main(String[] args) {
ArrayList<String> list = new ArrayList<>();
list.add("aaa");
list.add("bbb");
list.add("ccc");
list.add("ddd");
list.add("eee");
ListIterator<String> listIterator = list.listIterator();
while(listIterator.hasNext()){
String element = listIterator.next();
if(element.equals("bbb")){
listIterator.set("xyz");
}
}
for (String element : list) {
System.out.println(element);
}
}
}
1.3.5 需求:使用ListIterator指定下标遍历元素
public class Test08 {
/**
* 知识点:深入迭代器 -- ListIterator
*
* 需求:使用ListIterator指定下标遍历元素
*/
public static void main(String[] args) {
ArrayList<String> list = new ArrayList<>();
list.add("aaa");
list.add("bbb");
list.add("ccc");
list.add("ddd");
list.add("eee");
ListIterator<String> listIterator = list.listIterator(1);
while(listIterator.hasNext()){
String element = listIterator.next();
System.out.println(element);
}
}
}
1.3.6 需求:使用ListIterator倒序遍历元素
package com.qf.iterator01;
import java.util.ArrayList;
import java.util.ListIterator;
public class Test09 {
/**
* 知识点:深入迭代器 -- ListIterator
*
* 需求:使用ListIterator倒序遍历元素
*/
public static void main(String[] args) {
ArrayList<String> list = new ArrayList<>();
list.add("aaa");
list.add("bbb");
list.add("ccc");
list.add("ddd");
list.add("eee");
ListIterator<String> listIterator = list.listIterator(list.size());
while(listIterator.hasPrevious()){
String element = listIterator.previous();
System.out.println(element);
}
}
}
2.迭代器底层
码源场景:
(注意:看源码找场景)
ArrayList<String> list = new ArrayList<>();
list.add("aaa");
list.add("bbb");
list.add("ccc");
list.add("ddd");
list.add("eee");
list.remove("bbb");
Iterator<String> it = list.iterator();
while(it.hasNext()){
String element = it.next();
System.out.println(element);
}
/**
* Iterator用于遍历Collection下的集合,Collection下的每个集合底层实现不一样,意味着遍历逻辑也不一样,
* 所以Java的设计者将Iterator设计成了接口,让Collection下的每个集合实现Iterator
*/
public interface Iterator<E> {
//判断是否有可迭代的元素
boolean hasNext();
//返回下一个元素
E next();
//删除(默认方法) -- 报错
default void remove() {
throw new UnsupportedOperationException("remove");
}
}
public abstract class AbstractList<E> extends AbstractCollection<E> implements List<E> {
//外部操作数(记录集合添加、删除的次数)
protected transient int modCount = 0;//6
}
public class ArrayList<E> extends AbstractList<E> implements List<E>{
//数据容器 - ["aaa","ccc","ddd","eee",null,null,null,null,null,null]
transient Object[] elementData;
//数据个数(指针)
private int size;//4
//e - "eee"
public boolean add(E e) {
ensureCapacityInternal(size + 1); // 判断是否扩容
elementData[size++] = e;
return true;
}
private void ensureCapacityInternal(int minCapacity) {
if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {
minCapacity = Math.max(DEFAULT_CAPACITY, minCapacity);
}
ensureExplicitCapacity(minCapacity);
}
private void ensureExplicitCapacity(int minCapacity) {
modCount++;
if (minCapacity - elementData.length > 0)
grow(minCapacity);
}
//o - "bbb"
public boolean remove(Object o) {
if (o == null) {
for (int index = 0; index < size; index++)
if (elementData[index] == null) {
fastRemove(index);
return true;
}
} else {
//线性查询(从头遍历到size的位置)
for (int index = 0; index < size; index++)
if (o.equals(elementData[index])) {
//删除元素(传入下标)
fastRemove(index);
return true;
}
}
return false;
}
//index - 1
private void fastRemove(int index) {
modCount++;
int numMoved = size - index - 1;//计算移动次数(移动长度)
if (numMoved > 0)
System.arraycopy(elementData, index+1, elementData, index, numMoved);
elementData[--size] = null; // clear to let GC do its work
}
public Iterator<E> iterator() {
return new Itr();
}
//Itr是成员内部类,因为Itr中使用到了外部类(ArrayList)的成员属性(modCount、size)
private class Itr implements Iterator<E> {
int cursor; // 游标 - 4
int lastRet = -1; // 当前元素的下标 - 3
int expectedModCount = modCount;//内部操作数 - 6
public boolean hasNext() {
return cursor != size;//4 != 4
}
@SuppressWarnings("unchecked")
public E next() {
checkForComodification();//判断外部操作数和内部操作数是否相同
int i = cursor;//i = 3
if (i >= size)
throw new NoSuchElementException();
//elementData - ["aaa","ccc","ddd","eee",null,null,null,null,null,null]
Object[] elementData = ArrayList.this.elementData;
if (i >= elementData.length)
throw new ConcurrentModificationException();
cursor = i + 1;//cursor - 4
return (E) elementData[lastRet = i];
}
final void checkForComodification() {
if (modCount != expectedModCount)
throw new ConcurrentModificationException();
}
public void remove() {
if (lastRet < 0)
throw new IllegalStateException();
checkForComodification();//判断外部操作数和内部操作数是否相同
try {
//Itr依赖于ArrayList对象的remove()去删除元素
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();
}
}
}