为了方便处理集合中的元素(获取或删除元素),Java中出现了一个对象,该对象就叫做迭代器(Iterator)。对 Collection 进行迭代的类,称其为迭代器。
由于每一个容器都有取出或删除元素的功能,这些功能定义都一样,只不过实现的具体方式不同(因为每一个容器的数据结构不一样),所以,在java中对共性的功能进行抽取并封装在Iterator接口中,从而出现了迭代器。在每一个容器内部都对该接口进行了内部类的实现,也就是将取出或删除元素的细节进行了封装。
迭代器使得对容器的遍历操作与其具体的底层实现相隔离,达到解耦的效果。
Java中使用Iterator来遍历集合元素,Iterator遍历集合元素有以下几个特点:
1.Iterator遍历集合元素的过程中不允许线程对集合元素进行修改,否则会抛出ConcurrentModificationException的异常。
2.Iterator遍历集合元素的过程中可以通过remove方法来移除集合中的元素。
3.Iterator必须依附某个Collection对象而存在,Iterator本身不具有装载数据对象的功能。
4.Iterator.remove方法删除的是上一次Iterator.next()方法返回的对象。
强调一下next方法,该方法通过游标指向的形式返回Iterator下一个元素。
如何获取迭代器(Iterator)?
JDK1.5新增了Iterable接口,该接口中只有iterator()一个方法,用于获取迭代器(Iterator)。Collection接口继承了Iterable接口,所以Collection体系都具备获取自身迭代器的方法,只不过每个子类集合都对iterator()方法进行了重写(因为数据结构不同)。
java.lang. Iterable
---| Iterable 接口,实现该接口可以使用增强for循环
---| Collection 描述所有集合共性的接口
---| List接口 可以有重复元素的集合
---| Set接口 不可以有重复元素的集合
迭代器Iterator的源码:
package java.util;
import java.util.function.Consumer;
public interface Iterator<E> {
//判断集合中是否有元素,如果有元素可以迭代,就返回true
boolean hasNext();
//返回迭代的下一个元素,若没有下一个元素,调用next方法会抛出NoSuchElementException
E next();
//从迭代器指向的集合中移除迭代器返回的最后一个元素(可选操作)
default void remove() {
throw new UnsupportedOperationException("remove");
}
default void forEachRemaining(Consumer<? super E> var1) {
Objects.requireNonNull(var1);
while(this.hasNext()) {
var1.accept(this.next());
}
}
}
Iterable接口的源码:
package java.lang;
import java.util.Iterator;
import java.util.Objects;
import java.util.Spliterator;
import java.util.Spliterators;
import java.util.function.Consumer;
public interface Iterable<T> {
Iterator<T> iterator();
//从JDK1.8开始,允许接口中有默认方法(default关键字修饰的)和静态方法
default void forEach(Consumer<? super T> var1) {
Objects.requireNonNull(var1);
Iterator var2 = this.iterator();
while(var2.hasNext()) {
Object var3 = var2.next();
var1.accept(var3);
}
}
default Spliterator<T> spliterator() {
return Spliterators.spliteratorUnknownSize(this.iterator(), 0);
}
}
Collection接口的源码,继承了Iterable接口:
package java.util;
import java.util.function.Predicate;
import java.util.stream.Stream;
import java.util.stream.StreamSupport;
public interface Collection<E> extends Iterable<E> {
int size();
boolean isEmpty();
boolean contains(Object var1);
Iterator<E> iterator();
Object[] toArray();
<T> T[] toArray(T[] var1);
boolean add(E var1);
boolean remove(Object var1);
boolean containsAll(Collection<?> var1);
boolean addAll(Collection<? extends E> var1);
boolean removeAll(Collection<?> var1);
default boolean removeIf(Predicate<? super E> var1) {
Objects.requireNonNull(var1);
boolean var2 = false;
Iterator var3 = this.iterator();
while(var3.hasNext()) {
if (var1.test(var3.next())) {
var3.remove();
var2 = true;
}
}
return var2;
}
boolean retainAll(Collection<?> var1);
void clear();
boolean equals(Object var1);
int hashCode();
default Spliterator<E> spliterator() {
return Spliterators.spliterator(this, 0);
}
default Stream<E> stream() {
return StreamSupport.stream(this.spliterator(), false);
}
default Stream<E> parallelStream() {
return StreamSupport.stream(this.spliterator(), true);
}
}
List接口的源码,继承了Collection接口:
package java.util;
import java.util.function.UnaryOperator;
public interface List<E> extends Collection<E> {
int size();
boolean isEmpty();
boolean contains(Object var1);
Iterator<E> iterator();
Object[] toArray();
<T> T[] toArray(T[] var1);
boolean add(E var1);
boolean remove(Object var1);
boolean containsAll(Collection<?> var1);
boolean addAll(Collection<? extends E> var1);
boolean addAll(int var1, Collection<? extends E> var2);
boolean removeAll(Collection<?> var1);
boolean retainAll(Collection<?> var1);
default void replaceAll(UnaryOperator<E> var1) {
Objects.requireNonNull(var1);
ListIterator var2 = this.listIterator();
while(var2.hasNext()) {
var2.set(var1.apply(var2.next()));
}
}
default void sort(Comparator<? super E> var1) {
Object[] var2 = this.toArray();
Arrays.sort(var2, var1);
ListIterator var3 = this.listIterator();
Object[] var4 = var2;
int var5 = var2.length;
for(int var6 = 0; var6 < var5; ++var6) {
Object var7 = var4[var6];
var3.next();
var3.set(var7);
}
}
void clear();
boolean equals(Object var1);
int hashCode();
E get(int var1);
E set(int var1, E var2);
void add(int var1, E var2);
E remove(int var1);
int indexOf(Object var1);
int lastIndexOf(Object var1);
ListIterator<E> listIterator();
ListIterator<E> listIterator(int var1);
List<E> subList(int var1, int var2);
default Spliterator<E> spliterator() {
return Spliterators.spliterator(this, 16);
}
}
ArrayList类中的部分源码:
public class ArrayList<E> extends AbstractList<E> implements List<E>, RandomAccess, Cloneable, Serializable {
private static final long serialVersionUID = 8683452581122892189L;
private static final int DEFAULT_CAPACITY = 10;
//省略了其他属性和方法
//获取ListIterator迭代器
public ListIterator<E> listIterator() {
return new ArrayList.ListItr(0);
}
//获取Iterator迭代器(获取迭代器的方法在具体子类中实现,即此处的iterator方法)
public Iterator<E> iterator() {
return new ArrayList.Itr();
}
//Itr内部类开始==================================================
//在ArrayList类中定义内部类Itr实现Iterator接口
private class Itr implements Iterator<E> {
int cursor;
int lastRet;
int expectedModCount;
//内部类Itr的构造器
private Itr() {
this.lastRet = -1;
this.expectedModCount = ArrayList.this.modCount;
}
//在内部类中覆盖了Iterator接口的hasNext方法
public boolean hasNext() {
return this.cursor != ArrayList.this.size;
}
//在内部类中覆盖了Iterator接口的next方法
public E next() {
this.checkForComodification();
int var1 = this.cursor;
if (var1 >= ArrayList.this.size) {
throw new NoSuchElementException();
} else {
Object[] var2 = ArrayList.this.elementData;
if (var1 >= var2.length) {
throw new ConcurrentModificationException();
} else {
this.cursor = var1 + 1;
return var2[this.lastRet = var1];
}
}
}
//在内部类中覆盖了Iterator接口的remove方法
public void remove() {
if (this.lastRet < 0) {
throw new IllegalStateException();
} else {
this.checkForComodification();
try {
ArrayList.this.remove(this.lastRet);
this.cursor = this.lastRet;
this.lastRet = -1;
this.expectedModCount = ArrayList.this.modCount;
} catch (IndexOutOfBoundsException var2) {
throw new ConcurrentModificationException();
}
}
}
//在内部类中覆盖了Iterator接口的forEachRemaining方法
public void forEachRemaining(Consumer<? super E> var1) {
Objects.requireNonNull(var1);
int var2 = ArrayList.this.size;
int var3 = this.cursor;
if (var3 < var2) {
Object[] var4 = ArrayList.this.elementData;
if (var3 >= var4.length) {
throw new ConcurrentModificationException();
} else {
while(var3 != var2 && ArrayList.this.modCount == this.expectedModCount) {
var1.accept(var4[var3++]);
}
this.cursor = var3;
this.lastRet = var3 - 1;
this.checkForComodification();
}
}
}
final void checkForComodification() {
if (ArrayList.this.modCount != this.expectedModCount) {
throw new ConcurrentModificationException();
}
}
}//Itr内部类结束==================================================
//ListItr内部类开始==================================================
private class ListItr extends ArrayList<E>.Itr implements ListIterator<E> {
ListItr(int var2) {
super(null);
this.cursor = var2;
}
public boolean hasPrevious() {
return this.cursor != 0;
}
public int nextIndex() {
return this.cursor;
}
public int previousIndex() {
return this.cursor - 1;
}
public E previous() {
this.checkForComodification();
int var1 = this.cursor - 1;
if (var1 < 0) {
throw new NoSuchElementException();
} else {
Object[] var2 = ArrayList.this.elementData;
if (var1 >= var2.length) {
throw new ConcurrentModificationException();
} else {
this.cursor = var1;
return var2[this.lastRet = var1];
}
}
}
public void set(E var1) {
if (this.lastRet < 0) {
throw new IllegalStateException();
} else {
this.checkForComodification();
try {
ArrayList.this.set(this.lastRet, var1);
} catch (IndexOutOfBoundsException var3) {
throw new ConcurrentModificationException();
}
}
}
public void add(E var1) {
this.checkForComodification();
try {
int var2 = this.cursor;
ArrayList.this.add(var2, var1);
this.cursor = var2 + 1;
this.lastRet = -1;
this.expectedModCount = ArrayList.this.modCount;
} catch (IndexOutOfBoundsException var3) {
throw new ConcurrentModificationException();
}
}
}//ListItr内部类结束==================================================
}
Iterator与ListIterator的区别:
1.Iterator可用来遍历Set和List集合,但是ListIterator只能用来遍历List。
2.Iterator对集合只能顺序向后遍历,ListIterator既可以前向遍历,也可以后向遍历。
3.ListIterator实现了Iterator接口,并新增了其他功能,比如:add()方法向集合中增加元素,set()方法修改集合中的元素,previousIndex()方法获取前一个元素的索引,nextIndex()方法获取后一个元素的索引等。Iterator只能遍历集合中的元素,不能新增和修改集合中的元素。