Java Collection集合的遍历方式

193 阅读2分钟

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);
}
  • 细节注意点
    1. 当迭代器已经指向集合的末尾,这时再调用next()方法获取元素,会报错:NoSuchElementException 没有这个元素异常
    2. 迭代器遍历完毕,游标不会复位
    3. 循环中只能用一次next()方法,如果要第二次遍历集合,只能再次获取一个新的迭代器对象
    4. 迭代器遍历时,不能用集合的方法进行增加或者删除,会报错: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();
    }
}