Collection的遍历方式
迭代器遍历
迭代器在遍历集合的时候是不依赖索引的
迭代器在Java中的类是Iterator,它是一种接口,迭代器是集合专用的遍历方式
在迭代器中定义了一种定位方式:cursor(译为”游标、指针“,以下统称游标),这个概念在列表迭代器ListIterator中被提出
Collection集合获取迭代器
| 方法名称 | 说明 |
|---|---|
| Iterator iterator() | 返回迭代器对象,游标指向0索引元素的前面 |
Iterator中的常用方法
| 方法名称 | 说明 |
|---|---|
| boolean hasNext() | 判断游标的后面是否有元素,有元素返回true,没有元素返回false |
| E next() | 获取游标后面的元素,同时游标后移一位 |
| void remove() | 移除最后一次通过next()方法获取的元素 |
Iterator<String> it = list.iterator();
while(it.hasNext()) {
String str = it.next();
System.out.println(str);
}
- 细节注意点
- 当迭代器已经指向集合的末尾,这时再调用next()方法获取元素,会报错:NoSuchElementException 没有这个元素异常
- 迭代器遍历完毕,游标不会复位
- 循环中只能用一次next()方法,如果要第二次遍历集合,只能再次获取一个新的迭代器对象
- 迭代器遍历时,不能用集合的方法进行增加或者删除,会报错:ConcurrentModificationException 并发修改异常
- 如果想要删除时,可以调用Iterator中提供的remove方法进行删除,想要添加暂时没有方法
增强for遍历
- 增强for的底层就是迭代器,为了简化迭代器的代码书写的
- 它是JDK5之后出现的,其内部原理就是一个Iterator迭代器
- 所有的单列集合和数组才能用增强for进行遍历
for (元素的数据类型 变量名 : 数组或集合) {
}
//s其实就是一个第三方变量,在循环的过程中依次表示集合中的每一个元素
for (String s : list) {
System.out.println(s);
}
- 细节
- 修改增强for中的变量,不会改变集合中原本的数据
Lambda表达式遍历
得益于JDK8开始的新技术Lambda表达式,提供了一种更简单、更直接的遍历集合的方式
| 方法名称 | 说明 |
|---|---|
| default void forEach(Consumer<? super T> action) | 结合Lambda遍历集合 |
//利用匿名内部类的形式
coll.forEach(new Consumer<String>() {
@Override
//s依次表示集合中的每一个数据
public void accept(String s) {
System.out.println(s);
}
});
//利用Lambda表达式的形式
coll.forEach((String s) -> {
System.out.println(s);
}
);
//再简化
coll.forEach(s -> System.out.println(s));
- forEach方法底层原理
- 通过for循环获取集合中的每一个元素
- 再将元素交给我们重写的antion.accept方法进行实现
@Override
public void forEach(Consumer<? super E> action) {
Object.requireNonNull(action);
final int expectedModCount = modCount;
final Object[] es = elementData;
final int size = this.size;
for (int i = 0; modCount == expectedModCount && i < size; i++) {
action.accept(elementAt(es, i));
}
if (modCount != expectedModCount) {
throw new ConcurrentModificationException();
}
}