Java集合(1)——Iterable接口和Iterator接口
集合类图
- Iterable 是Java.lang包下的接口
- Iterabtor是java.util包下的接口
- Iterable接口包装了Iterator接口
java.lang.Iterable接口
官方文档介绍:
Implementing this interface allows an object to be the target of the “for-each loop” statement
翻译:Iterable接口作为超级接口,这个接口只有一个方法,该方法返回值类型是Iterator,方法名称为iterator()
,实现这个接口的对象可称为“for–each”语句的目标
- Iterable接口中的方法 (在jdk1.8中又增添了两个default方法)
public interface Iterable<T> {
Iterator<T> iterator();
default void forEach(Consumer<? super T> action) {
Objects.requireNonNull(action);
for (T t : this) {
action.accept(t);
}
}
default Spliterator<T> spliterator() {
return Spliterators.spliteratorUnknownSize(iterator(), 0);
}
}
java.util.Iterator接口
官方文档介绍:
An iterator over a collection. Iterator takes the place of Enumeration in the Java Collections Framework. Iterators differ from enumerations in two ways:
(1) Iterators allow the caller to remove elements from the underlying collection during the iteration with well-defined semantics.
(2) Method names have been improved.
翻译:集合上的迭代器。在集合框架中,Iterator迭代器取代了Enumeration。Iterator与Enumeration有两点不同
(1) 迭代器允许调用者在迭代过程中从定义良好的语义中删除底层集合中的元素。
(2) 名称比原来变短了。(可能大家都不愿意打那么长的名字。。。)
- Iterator接口中的方法
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());
}
}
- 通过调用
next()
方法,可以逐个访问集合中的每个元素,但是如果到达了集合的末尾,next()
方法将会抛出一个NoSuchElementException
异常,因此需要在调用next()
方法钱先调用hashNext()
方法判断是否还有元素 - Iterator接口的remove方法将会删除上次调用
next()
方法时返回的元素,next()
方法和remove()
方法的调用具有相互依赖性。如果调用remove()
之前没有调用next()
方法将是不合法的。如果这样做,将会抛出一个IllegalStateException
异常 - 每一种集合类返回的Iterator具体类型可能不同,Array可能返回ArrayIterator,Set可能返回SetIterator,Tree可能返回TreeIterator。但是他们都实现了Iterator接口。因此,客户端不需要关心到底是哪种Iterator,它只需要获得这个Iterator接口即可,这就是面向对象的威力。
使用Iterator的好处
- 在不使用Iterator时,遍历集合:
for(int i = 0; i < list.size(); i++){
}
- 在使用Iterator时,遍历集合:
Iterator i = nums.iterator();
while (iterator.hasNext()){
System.out.println(iterator.next());
}
Iterable接口与Iterator接口之间的关系
- 在集合中很多类都实现了Iterable接口。因为Collection是Iterable接口的子接口,集合中很多接口都继承Collection接口,出了Map接口
-
Iterator()
是用于遍历集合类的标准访问方法。它可以把访问逻辑从不同类型的集合类中抽象出来,从而避免像客户端暴露集合的内部结构 -
那为什么一定要实现Iterable接口,为什么不直接实现Iterator接口呢?
- 看一下JDK中的集合类,比如List和Set,都实现了Iterable接口,但是并没有实现Iterator接口。仔细想一下这么做是有道理的。
- 因为Iterator接口的核心方法
next()
或者hasNext()
是依赖于迭代器的当前迭代位置的。如果Collection直接实现iterator接口,势必导致集合对象中包含当前迭代位置的数据(指针)。当集合在不同方法间被传递时,由于当前迭代为止不可知,那么next()
方法的结果就会变得不可知。除非再为Iterator接口添加一个reset()
方法,用来重置当前迭代位置。但即使是这样,Collection也只能同时存在一个当前迭代位置。而Iterable接口则不然,每次调用都会返回一个从头开始计数的迭代器。多个迭代器之间是互不干扰的。
上一篇: python 抽象类 定义
推荐阅读
-
Java集合(1)——Iterable接口和Iterator接口
-
java Iterator接口和LIstIterator接口分析
-
java Iterator接口和LIstIterator接口分析
-
荐 JAVA13——容器(Map接口、Equals和hashcode、Set接口、容器存储数据练习、Iterator接口)
-
【java读书笔记】——Collection集合之六大接口(Collection、Set、List、Map、Iterator和Comparable)
-
20200729集合框架与泛型(Iterator接口,Map接口,Collection类和泛型)
-
java集合框架以及collection接口,list集合map集合和set集合
-
Java 面试系列 ——1.Java基础 接口和抽象类
-
荐 JAVA13——容器(Map接口、Equals和hashcode、Set接口、容器存储数据练习、Iterator接口)
-
Java 集合学习之——Java 的Iterable接口的使用