Java知识:集合遍历的几种方法
来源:互联网 发布:python书单 编辑:程序博客网 时间:2024/06/14 23:59
概述
集合的知识十分重要,那么集合有几种遍历方法,他们的各自特点有是什么、各自的适用场合又是怎样的呢?
Java遍历方式写法:
1、传统的for循环遍历,基于计数器的:
写法为:
for (int i = 0; i < list.size(); i++) { list.get(i); }
2、迭代器遍历,Iterator:
写法为:
Iterator iterator = list.iterator(); while (iterator.hasNext()) { iterator.next(); }
3、foreach循环遍历:
写法为:
for(ElementType element:list){}
每个遍历方式的实现原理是什么?
1、传统的for循环遍历,基于计数器的:
遍历者自己在集合外部维护一个计数器,然后依次读取每一个位置的元素,当读取到最后一个元素后,停止。主要就是需要按元素的位置(下标)来读取元素。
2、迭代器遍历,Iterator:
每一个具体实现的数据集合,一般都需要提供相应的Iterator。相比于传统for循环,Iterator取缔了显式的遍历计数器。所以基于顺序存储集合的Iterator可以直接按位置访问数据。而基于链式存储集合的Iterator,正常的实现,都是需要保存当前遍历的位置。然后根据当前位置来向前或者向后移动指针。
3、foreach循环遍历:
根据反编译的字节码可以发现,foreach内部也是采用了Iterator的方式实现,只不过Java编译器帮我们生成了这些代码。
各遍历方式对于不同的存储方式,性能如何?
1、传统的for循环遍历,基于计数器的:
因为是基于元素的位置,按位置读取。所以我们可以知道,对于顺序存储,因为读取特定位置元素的平均时间复杂度是O(1),所以遍历整个集合的平均时间复杂度为O(n)。而对于链式存储,因为读取特定位置元素的平均时间复杂度是O(n),所以遍历整个集合的平均时间复杂度为O(n2)(n的平方)。
2、迭代器遍历,Iterator:
那么对于RandomAccess类型的集合来说,没有太多意义,反而因为一些额外的操作,还会增加额外的运行时间。但是对于Sequential Access的集合来说,就有很重大的意义了,因为Iterator内部维护了当前遍历的位置,所以每次遍历,读取下一个位置并不需要从集合的第一个元素开始查找,只要把指针向后移一位就行了,这样一来,遍历整个集合的时间复杂度就降低为O(n);
3、foreach循环遍历:
分析Java字节码可知,foreach内部实现原理,也是通过Iterator实现的,只不过这个Iterator是Java编译器帮我们生成的,所以我们不需要再手动去编写。但是因为每次都要做类型转换检查,所以花费的时间比Iterator略长。时间复杂度和Iterator一样。
各遍历方式的适用于什么场合?
1、传统的for循环遍历,基于计数器的:
顺序存储:读取性能比较高。适用于遍历顺序存储集合。
链式存储:时间复杂度太大,不适用于遍历链式存储的集合。
2、迭代器遍历,Iterator:
顺序存储:如果不是太在意时间,推荐选择此方式,毕竟代码更加简洁,也防止了Off-By-One的问题。
链式存储:意义就重大了,平均时间复杂度降为O(n),还是挺诱人的,所以推荐此种遍历方式。
3、foreach循环遍历:
foreach只是让代码更加简洁了,但是他有一些缺点,就是遍历过程中不能操作数据集合(删除等),所以有些场合不使用。而且它本身就是基于Iterator实现的,但是由于类型转换的问题,所以会比直接使用Iterator慢一点,但是还好,时间复杂度都是一样的。所以怎么选择,参考上面两种方式,做一个折中的选择。
Java的最佳实践是什么?
Java数据集合框架中,提供了一个RandomAccess接口,该接口没有方法,只是一个标记。通常被List接口的实现使用,用来标记该List的实现是否支持Random Access。
一个数据集合实现了该接口,就意味着它支持Random Access,按位置读取元素的平均时间复杂度为O(1)。比如ArrayList。
而没有实现该接口的,就表示不支持Random Access。比如LinkedList。
所以看来JDK开发者也是注意到这个问题的,那么推荐的做法就是,如果想要遍历一个List,那么先判断是否支持Random Access,也就是 list instanceof RandomAccess。
if (list instanceof RandomAccess) { //使用传统的for循环遍历。 } else { //使用Iterator或者foreach。 }
本文基本全部摘抄别人的,原文链接如下:
http://blog.csdn.net/hjf_huangjinfu/article/details/51220253
- Java知识:集合遍历的几种方法
- Java几种集合的遍历方法
- 在Java中遍历Map集合的几种方法
- 关于几种方法对java集合的遍历
- 几种遍历list集合的方法
- 几种遍历集合的方法
- Java遍历集合的几种方法分析(实现原理、算法性能、适用场合)
- Java遍历集合的几种方法分析(实现原理、算法性能、适用场合)
- Java遍历集合的几种方法分析(实现原理、算法性能、适用场合)
- 遍历集合的常见的几种方法
- 集合的几种遍历
- java三种遍历集合的方法
- Java 遍历Map的几种方法
- java Map 遍历的几种方法
- java 几种遍历map的方法
- 遍历map的几种方法 java
- Java遍历Map的几种方法
- Java种遍历Map集合的几种常用方式
- 根据身份证号计算年龄、性别
- 算法与数据结构-Hash表的理解
- BZOJ 1072 [SCOI 2007] 状压DP 解题报告
- TYVJ 4864 天天去哪吃 || 清北学堂金秋杯大奖赛
- 23种设计模式(4):建造者模式
- Java知识:集合遍历的几种方法
- GEOServer-OpenLayer-矢量切片3:PBF格式格式展示(tms服务)
- Android Studio快速将字符串定义到strings.xml文件的方法
- java 二维码生成
- Android魔术(第五弹)—— 一步步实现滑动折叠列表
- 语言大数据起航,大数据量级加码
- [洛谷P1353] [USACO08JAN]跑步Running [DP]
- java中的Activity
- Android日历阴阳历转换的实现(包括日期选择器)