目录
前言
我们之前使用的for遍历方式是通过索引来遍历的,但是我们现在学习的Collection集合体系中的Set系列集合并没有索引,那么我们应该如何去遍历Collection集合体系中的系列集合呢?Java 为我们提供了三种通用的遍历。
- 迭代器遍历
- 增强for遍历
- Lambda表达式遍历
一、迭代器遍历
迭代器在Java中的类是Iterator,迭代器是集合专用的遍历方式。
Collection集合获取迭代器:
javaIterator<E> iterator() 返回迭代器对象,默认指向当前集合的0索引Iterator中的常用方法:
javaboolean hasNext() 判断当前位置是否有元素,有元素返回true,无元素返回false。 E next() 获取当前位置的元素,并将迭代器对象移向下一个位置。
1.使用方式
java
import java.util.ArrayList;
import java.util.Iterator;
public class IteratorDemo01 {
public static void main(String[] args) {
ArrayList<String> al = new ArrayList<>();
al.add("Java");
al.add("C++");
al.add("Python");
al.add("MySql");
Iterator<String> it = al.iterator();
while(it.hasNext()){
String str = it.next();
System.out.println(str);
}
}
}
运行结果:
2.细节点
- 运行到没有元素的位置时,如果强行调用next方法,会报NoSuchElementException异常。
- 迭代器遍历完毕后,指针不会复位。
- 循环中只能用一次next方法。
- 迭代器遍历时,不能用集合的方法进行增加或者删除。


由此看出迭代器并不会复位,以及如果强行调用next方法,会报NoSuchElementException异常。
如果我们要继续第二次遍历集合,只能再次获取一个新的迭代器对象。
当我们使用Collection自带的删除方法时
java
public class IteratorDemo01 {
public static void main(String[] args) {
Collection<String> al = new ArrayList<>();
al.add("Java");
al.add("C++");
al.add("Python");
al.add("MySql");
Iterator<String> it = al.iterator();
while(it.hasNext()){
String str = it.next();
if("C++".equals(str)){
al.remove("C++");
}
}
System.out.println(al);
}
}
正确方式:it.remove();
小结
- 迭代器在遍历集合时是不依赖索引的
- 迭代器需要掌握的三个方法
- 迭代器的四个细节
二、增强for遍历
增强for的底层就是迭代器,是为了简化迭代器的代码而出现的。
所有的单列集合和数组才能用增强for进行遍历。
格式:
for(元素的数据类型 变量名:数组或者集合){
}
1.使用方式
java
public class IteratorTest01 {
public static void main(String[] args) {
Collection<String> coll = new ArrayList<>();
coll.add("aaa");
coll.add("bbb");
coll.add("ccc");
coll.add("ddd");
coll.add("eee");
for(String str : coll){
System.out.println(str);
}
}
}
运行结果:
2.细节点
- 修改增强for中的变量,不会改变集合中原本的数据。因为我们设置的访问的变量只是一个第三方变量,修改第三方变量并不会将源数据改变。
三、Lambda表达式遍历
得益于JDK 8开始的新技术Lambda表达式,提供了一种更简单、更直接的遍历集合的方式。
方法:
default void forEach(Consumer<? super T> action):
1.使用方式
java
// 第一阶段:匿名内部类
list.forEach(new Consumer<String>() {
@Override
public void accept(String s) {
System.out.println(s);
}
});
// 第二阶段:砍掉 new 接口、Override 那些废话
// 编译器:我知道这里需要一个 Consumer,而且 Consumer 只有 accept 这一个方法。
list.forEach( (String s) -> { System.out.println(s); } );
// 第三阶段:砍掉参数类型
// 编译器:list 集合存的是 String,我当然知道传进来的 s 是 String 类型。
list.forEach( (s) -> { System.out.println(s); } );
// 第四阶段:如果参数只有一个,大括号只有一行代码,砍掉参数小括号、核心代码大括号和分号。
// 终极形态:Lambda 表达式
list.forEach(s -> System.out.println(s));
-
():方法的参数列表。如果没有参数,写空括号()。如果只有一个参数,可以不写括号s。 -
->:Lambda 操作符,读作"goes to "或者"由它引出"。它把参数和核心逻辑连接起来。 -
{}:方法体(核心逻辑)。如果只有一行代码,可以不写大括号、return和分号。
总结
- 迭代器:在遍历的过程中需要删除元素,请使用迭代器。
- 增强for、Lambda:仅仅想遍历,那么使用增强for、Lambda表达式。

