Collection接口与Iterator接口

it2025-07-28  10

文章目录

Collection接口与Iterator接口1. Iterable接口2. Iterator接口3. Iterator接口的实现类4.遍历4.1 概述4.2 用foreach()来遍历集合4.3 用forEach()方法来遍历4.4 用Iterator接口的实现类提供的 hasNext(),next()遍历集合4.5 用Iterator接口的实现类提供的forEachRemaining()方法来遍历集合 5. Collection定义的操作集合元素的方法

Collection接口与Iterator接口

1. Iterable接口


Iterable是Collection接口的父接口, 它主要提供了一个方法iterator()方法,和foreach()方法,他们都是用来遍历集合中的元素的。iterator()方法返回一个Iterator的实现类,Iterator的实现类都是继承类一个叫做Iterator的接口。

/** * Returns an iterator over elements of type {@code T}. * * @return an Iterator. */ Iterator<T> iterator(); default void forEach(Consumer<? super T> action) { Objects.requireNonNull(action); for (T t : this) { action.accept(t); } }

2. Iterator接口


接口规定Iterator接口的实现类必须要实现 hasNext(), next()方法,forEachRemaining .

这些方法就可以帮助我们遍历。

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

3. Iterator接口的实现类


我们上面说了,iterator()方法返回的是Iterator接口的实现类,这个实现类是由具体的集合实现的。拿ArrayList举例子,Iterator接口的实现类叫做 Itr。它里面具体实现了hasNext(), next(), remove(), 并重写了forEachRemaining()方法。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-OmlNHb1z-1603329302425)(/Users/luca/MarkText-img-Support/2020-05-21-10-32-17-image.png)]

4.遍历

4.1 概述


Collection继承Iterable接口,Iterable要求实现Collection接口的实现类必须实现forEach()方法,所以我们可以通过forEach()方法来遍历;

Iterable接口还要求实现Collection的实现类必须实现iterator()方法,他要返回一个实现Iterator接口的实现类,而这个Iterator接口的实现类必须要有hasNext(),next() 和forEachRemaining()方法,而这三个方法不是用来操作Iterator的实现类的,是用来操作这个具体的集合的。 我们可以通过hasNext(),next()来完成遍历;也可以通过forEachRemaining()方法完成遍历。

但注意,这三种方法只能用于继承Collection接口的集合,而不能用于继承Map接口的集合,因为Map没有继承Iterable接口。在下一篇文章中我将详细的讲Map。

我想强调一下,不要以为那些hasNext(),next() forEach() 很高深,我们在写一些算法题实现遍历数组也好,链表也好,其实实现的东西和这几个函数实现的东西一样,只不过java库使用了这一些方法来遍历,而你是使用自己写的算法来实现,去看具体的实现源码都是非常容易看懂的。

4.2 用foreach()来遍历集合


java5后,Java提供来一种使得循环迭代集合更加的便捷的方法——foreach()。(这个foreach()和上面的不一样,这个是小写的)。它即可以遍历集合也可以遍历数组。

例子:

var books = new ArrayList(); books.add("12"); books.add("22"); books.add("32"); books.add("42"); books.add("52"); for(var book : books) { //对元素操作 System.out.println(book); }

4.3 用forEach()方法来遍历


java8后,Iterable要求实现Collection接口的实现类必须实现forEach()方法,Collection下的每一个集合都有各自实现的forEach(),(其实Map接口也定义了forEach方法,也是用来遍历的)

default void forEach(Consumer<? super T> action) { Objects.requireNonNull(action); for (T t : this) { action.accept(t); } }

这是该函数的原型,forEach(Consumer action)要求你提供一个方法叫action(可以使用lambada),当你对集合的某一实例调用forEach方法时,该方法会将集合的每一个元素放进你提供你方法里面处理。细看一眼,其实forEach()的底层就是用foreach()实现的(你注意一下时间 foreach是java5就有的,forEach是java8后才有的)。

为什么java5已经有了foreach,为什么java8还要写一个forEach,而且它底层还是使用foreach。难道java的开发人员是傻子吗。不对!每一种方法存在都有他们的意义,仔细想一想,其实你使用forEach就可以把处理元素的过程打包成为一个方法,封装起来,就达到了代码的复用,降低了耦合性。

(这可能只是使用他的作用之一)

例子:

var books = new ArrayList(); books.add("12"); books.add("22"); books.add("32"); books.add("42"); books.add("52"); books.forEach(obj-> System.out.println(obj));

4.4 用Iterator接口的实现类提供的 hasNext(),next()遍历集合


E next(); boolean hasNext();

这是这两个方法的原型,这样是看不出什么来的,还是要看具体的实现,看具体的实现又不具有代表性。所以我就直接说一下用法,就不具体分析源码了。

boolean hasNext():如果被迭代的集合元素还没有遍历完则返回true,

next():返回下一个元素。

同时Iterator的实现类又一个remove()方法: 删除集合里上一次next方法返回的元素。

使用的例子:

var books = new ArrayList(); books.add("12"); books.add("22"); books.add("32"); books.add("42"); books.add("52"); var it = books.iterator(); while(it.hasNext()){ //对元素操作 it.remove(); }

4.5 用Iterator接口的实现类提供的forEachRemaining()方法来遍历集合


来看一下源码

default void forEachRemaining(Consumer<? super E> action) { Objects.requireNonNull(action); while (hasNext()) action.accept(next()); }

在提供hasNext(),next()之外,Iterator的实现类还提供forEachRemaining

forEachRemaining与hasNext(), next()的关系 和 foreach()与 forEach()的关系一样。

forEachRemaining 底层也是用hasNext(),next()实现的。所以这里就不再做过多的赘述了。

例子:

var books = new ArrayList(); books.add("12"); books.add("22"); books.add("32"); books.add("42"); books.add("52"); var it = books.iterator(); it.forEachRemaining(obj -> System.out.println(obj));

5. Collection定义的操作集合元素的方法


boolean add(Object o): 该方法用于向集合里添加一个元素。如果集合对象被添加操作改变了,则返回 true

boolean addAll(Collection c): 该方法把集合c里的所有元素添加到指定集合里。如果集合对象被添加操作该表了,则返回 true

void clear(): 清除集合里的所有元素,将集合长度变为 0

boolean contains(Object o): 返回集合里是否包含制定元素

boolean containsAll(Collection c): 返回集合里是否包含集合c里的所有元素

boolean isEmpty(): 返回集合是否为空。当集合长度为0时返回 true,否则返回 false

Iterator iterator():返回一个 Iterator 对象,用于遍历集合里的元素

boolean remove(Object o): 删除集合中的指定元素o,当集合中包含了一个或多个元素 o 时,该方法只删除第一个符合条件的元素,该方法返回 true

boolean removeAll(Collection c): 从集合中删除集合 c 里包含的元素(相当于把调用该方法的集合减集合 c),如果删除了一个或多个以上的元素,该方法返回 true

boolean retainAll(Collection c): 从集合中删除集合 c 里不包含的元素(相当于把调用该方法的集合变成该集合和集合 c 的交集),如果该操作改变了调用该方法的集合,则该方法返回 true

int size():该方法返回集合里元素的个数

Object[] toArray(): 该方法把集合转换成一个数组,所有的集合元素变成对应的数组元素

removeIf(Predicate filter): Java8为Collection接口新增的方法,该方法将会批量删除符合filter条件的所有元素。该filter是Predicate对象,Predicate是函数式接口,所以我们可以用lambda表达式来作为这个方法的参数

通过Stream来操作集合:java8还新增了Stream,IntStream,LongStream,DoubleStream等流式API。这里的知识体量很大,可以自行参考以上各种API的文档。

最新回复(0)