(学习笔记)for循环和forEach性能差异对比

1.写法比较
第一种:普通for循环格式:
for(表达式1;循环条件;表达式2){
    ...循环体
}

第二种:增强for循环格式:
for(类 类的别名 : 类的集合){
    ...循环体
}

第三种:iterator 格式:
Iterator<Integer> iterator = arrayList.iterator();
while (iterator.hasNext()) {
    iterator.next();
}

基于增强for实现的扩展写法 forEach:
List list = new ArrayList();
list.forEach(x -> {
    ...循环体
});

Map<String, List<Object>> mapBy = new HashMap<>();
mapBy.forEach((key, value) -> {
    List<Object> = value;
    ...循环体
});

2.性能比较
一般情况下,使用forEach循环的性能要高出普通for循环20%左右。

3.原理比较
区别:
普通for是依靠遍历,增强for是依靠迭代器
foreach 只能用于遍历,不能更改循环目标,遍历速度快,执行效率高。
for 循环可以用于任何形式的重复行为,在循环体中可以进行任何操作,遍历速度慢,执行效率低。

4.特殊应用
ArrayList 和 LinkList
ArrayList 底层数据结构就是Array数组,数组的数据结构在内存中的表现是一段有序的连续内存,所以插入和删除较慢,查询较快
LinkList 底层数据结构就是Link 链表,特点是数据不需要存储在连续的内存块,而且读数据一定是按顺序依次判断读取,查询慢,增删快。
顺序式列表用三种遍历的任意一种,时间复杂度都是O(n)。而链式列表用普通for循环遍历,时间复杂度是O(n^2),但是如果链式列表用增强型for循环、迭代器循环的时间复杂度是O(n),相差了一个数量级的时间,所以链式列表用普通for循环遍历会很慢。

首先,对于列表的增强型for循环,其实是等同于迭代器循环的。
循环ArrayList的情况:
普通for循环效率要高于foreach, 但也相差不多
for循环采用下标访问,符合数组数据结构的查询方式,每次循环会调用底层get(index)方法取出一个位置上的元素,方法的时间复杂度为O(1),是一个常数,所以遍历数组推荐使用普通for循环。
foreach 是iterator迭代器方式遍历,每次循环中会使用迭代器中hasNext和next函数,

循环LinkList的情况:
链表中的数据不是有序的,而相邻节点通过每个节点中next()方法存储的下一个节点的地址关联,这就导致每次循环中,在get任何一个位置的数据时都会把前面的数据走一遍,
从这里就可以看出,链式列表寻找一个元素的效率就比顺序式列表寻找一个元素的效率要低很多了,因为顺序式列表寻找一个元素的时间复杂度是O(1),链式列表寻找一个元素的时间复杂度是O(n)。
因为要有n个元素需要遍历,所以链式列表遍历n个元素的时间复杂度是O(n^2),链式列表的普通for循环很慢,比顺序式列表的普通for循环慢了一个数量级。

对于链式列表,使用普通for循环遍历,每次get方法的时间复杂度是O(n),但是使用迭代器循环遍历,每次next方法的时间复杂度是O(1),所以能够大幅减低时间。而链式列表之所以每次next方法的时间复杂度是O(1),
是因为每次next方法都是将指针向后移动一位,而不是像普通for循环的get方法那样从头到尾寻找一次。
所以综上所述可以看到,对于链式列表的增强型for循环(迭代器循环),每次next方法的时间复杂度是O(1),遍历n个元素的时间复杂度是O(n)

总结:
ArrayList通过普通for循环遍历10万条数据,花费2ms,时间复杂度O(n)。
ArrayList通过增强型for循环遍历10万条数据,花费2ms,时间复杂度O(n)。
ArrayList通过迭代器循环遍历10万条数据,花费2ms,时间复杂度O(n)。

LinkedList通过普通for循环遍历10万条数据,花费4390ms,时间复杂度O(n^2),明显慢很多。
LinkedList通过增强型for循环遍历10万条数据,花费3ms,时间复杂度O(n)。
LinkedList通过迭代器循环遍历10万条数据,花费1ms,时间复杂度O(n)。

结论:
基于数组实现的集合,使用普通for循环遍历数据
基于链表实现的集合,使用增强型for循环遍历数据

  • 4
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值