你可能不清楚的Java细节(2)--for及for-each各自循环适用的场景
来源:互联网 发布:sql server创建视图 编辑:程序博客网 时间:2024/05/15 14:19
本文参考资料基于JDK1.8,理论上也适用于之前的版本.
严格的说,for-each是对for的增强,本质上也属于for循环.
for和for-each一般无非也就是如下三种用法,其中第三种也就是我们平时所说的for-each:
//其中list为java.util.List类型//第一种写法for (int i=0, n=list.size(); i < n; i++){ list.get(i);}//第二种写法for (Iterator i=list.iterator(); i.hasNext(); ){ i.next();}//第三种写法:增强型for循环,即for-each for(T obj : list){ //TODO}
经常在写for循环的时候会很困惑:到底用哪种写法最合适.
一步步来看.
在JLS第14.14.2章节 The enhanced for statement中对for-each的有说明,原文太长有兴趣可以点进去自行去看,大体上就是说:
- 能使用for-each进行循环的对象,要么是直接或间接的实现了Iterable接口,要么就是个数组.
- 如果是数组,那么在执行的时候JVM会解释成如下形式,即第一种写法:
for (int i=0, n=list.size(); i < n; i++){
list.get(i);
}
//特别要注意,是解释成上面这种写法,而不是下面这样的.毕竟前者的在性能上会更好一些.
for (int i=0; i < list.size(); i++){
list.get(i);
}
3.如果是实现了Iterable接口,那么在执行的时候JVM会解释成如下形式,即第二种写法:
for (Iterator i=list.iterator(); i.hasNext(); ){ i.next(); }
而JDK中Iterable接口的API也指明了该接口是为了让实现类成为for-each语句的目标.
鉴于在执行时JVM会根据对象是数组还是Iterable接口的实现类来自行决定解释成具体哪种形式的写法,因此,虽然for-each有它的局限性,但大部分情况下,我们都可以用for-each替代for,毕竟for-each可以让代码显得更简洁逻辑也更清晰.
但是,还是有例外的情况,那就是既实现了Iterable又实现了RandomAccess的类,比如最常见的ArrayList.
RandomAccess的API中有指明,实现了RandomAccess接口的类(准确的说,是属于随机访问的List,因为属于随机访问的List应当实现RandomAccess接口),在进行循环时,更适合采用第一种写法(自然也就不适合使用for-each,因为for-each只会判断是不是数组、是不是实现了Iterable接口,并没有对是否实现RandomAccess进行判断).
所以,整个的结论就是:
- 如果是数组,则采用第一种或第三种.
- 如果是实现了Iterable接口,并且未实现RandomAccess接口(不是随机访问的List),则应当使用第二种或第三种,优先使用第三种即for-each.
- 如果是实现了Iterable接口,并且实现了RandomAccess接口(是随机访问的List),则应当使用第一种.
参考资料:
- JLS第14.14.2章节 The enhanced for statement
- JDK1.8 API
- 你可能不清楚的Java细节(2)--for及for-each各自循环适用的场景
- Java的Iterator和for-each 循环
- Java中For-Each循环的使用
- Java 增强型的for循环 for each
- java 增强型的for循环 for each
- Java 增强型的for循环 for each
- Java 增强型的for循环 for each 【转载】
- Java 增强型的for循环 for each
- Java 增强型的for循环 for each
- Java 增强型的for循环 for each
- Java 增强型的for循环 for each
- Java 增强型的for循环 for each
- Java 增强型的for循环 for each
- java 增强型的for循环 for each
- for each循环的作用
- for each和for循环的对比
- 增强的for循环(for each)
- JAVA for each 循环
- python 时间模块: datetime
- 程序11-先升序后降序返回最大值
- 封装和private关键字
- 源码-数据库调优(tuning)初接触
- 1-1 C++ learning
- 你可能不清楚的Java细节(2)--for及for-each各自循环适用的场景
- 关于今天笔试关于java一些基础题的疑惑
- 初探Docker
- this关键字
- c语言----交换a,b的值(分别用临时变量,加减法,异或实现)
- 解决listview加载网络图片乱跳
- 构造方法
- android事件分发源码解析(下)
- Fragment的使用