java基础之foreach
来源:互联网 发布:vb倒计时显示剩余时间 编辑:程序博客网 时间:2024/04/28 01:50
foreach实现原理
集合和数组可以用foreach进行元素访问是因为实现了java.lang.Iterable接口。
jdk api文档中是这样描述Iterable接口的:实现这个接口允许对象成为 "foreach" 语句的目标。不过咋一看Iterable接口并没啥特别之处,只是定义了一个迭代器而已。
public interface Iterable<T> { /** * Returns an iterator over a set of elements of type T. * * @return an Iterator. */ Iterator<T> iterator(); }
我们只需要知道一下事实就好
(1)For-each语法内部,对collection是用nested iteratoration来实现的,对数组是用下标遍历来实现。
(2)Java 5 及以上的编译器隐藏了基于iteration和下标遍历的内部实现。(注意,这里说的是“Java编译器”或Java语言对其实现做了隐藏,而不是某段Java代码对其实现做了隐藏,也就是说,我们在任何一段JDK的Java代码中都找不到这里被隐藏的实现。这里的实现,隐藏在了Java 编译器中,我们可能只能像这篇帖子中说的那样,查看一段For-each的Java代码编译成的字节码,从中揣测它到底是怎么实现的了)
下面对“For-each”和“其对等的iteration/index实现”的对比再简洁明了不过了。
For-each loopEquivalent for loop
for (type var : arr) { body-of-loop}
for (int i = 0; i < arr.length; i++) { type var = arr[i]; body-of-loop}
for (type var : coll) { body-of-loop}
for (Iterator<type> iter = coll.iterator(); iter.hasNext(); ) { type var = iter.next(); body-of-loop}
foreach的限制
(1)使用For-each时对collection或数组中的元素不能做赋值操作。
(2)同时只能遍历一个collection或数组,不能同时遍历多余一个collection或数组。
(3)遍历过程中,collection或数组中同时只有一个元素可见,即只有“当前遍历到的元素”可见,而前一个或后一个元素是不可见的。
(4)只能正向遍历,不能反向遍历(相比之下,C++ STL中还有reverse_iterator, rbegin(), rend()之类的东西,可以反向遍历)。
(5)如果要兼容Java 5之前的Java版本,就不能使用For-each。
foreach和for的性能对比
今天我们来比较一下两种for循环对ArrayList和LinkList集合的循环性能比较。首先简单的了解一下ArrayList和LinkList的区别:
ArrayList:ArrayList是采用数组的形式保存对象的,这种方式将对象放在连续的内存块中,所以插入和删除时比较麻烦,查询比较方便。
LinkList:LinkList是将对象放在独立的空间中,而且每个空间中还保存下一个空间的索引,也就是数据结构中的链表结构,插入和删除比较方便,但是查找很麻烦,要从第一个开始遍历。
public static void main(String[] args) { //实例化arrayList List<Integer> arrayList = new ArrayList<Integer>(); //实例化linkList List<Integer> linkList = new LinkedList<Integer>(); //插入10万条数据 for (int i = 0; i < 100000; i++) { arrayList.add(i); linkList.add(i); } int array = 0; //用for循环arrayList long arrayForStartTime = System.currentTimeMillis(); for (int i = 0; i < arrayList.size(); i++) { array = arrayList.get(i); } long arrayForEndTime = System.currentTimeMillis(); System.out.println("用for循环arrayList 10万次花费时间:" + (arrayForEndTime - arrayForStartTime) + "毫秒"); //用foreach循环arrayList long arrayForeachStartTime = System.currentTimeMillis(); for(Integer in : arrayList){ array = in; } long arrayForeachEndTime = System.currentTimeMillis(); System.out.println("用foreach循环arrayList 10万次花费时间:" + (arrayForeachEndTime - arrayForeachStartTime ) + "毫秒"); //用for循环linkList long linkForStartTime = System.currentTimeMillis(); int link = 0; for (int i = 0; i < linkList.size(); i++) { link = linkList.get(i); } long linkForEndTime = System.currentTimeMillis(); System.out.println("用for循环linkList 10万次花费时间:" + (linkForEndTime - linkForStartTime) + "毫秒"); //用froeach循环linkList long linkForeachStartTime = System.currentTimeMillis(); for(Integer in : linkList){ link = in; } long linkForeachEndTime = System.currentTimeMillis(); System.out.println("用foreach循环linkList 10万次花费时间:" + (linkForeachEndTime - linkForeachStartTime ) + "毫秒");}
循环10万次的时候,控制台打印结果:结论:需要循环数组结构的数据时,建议使用普通for循环,因为for循环采用下标访问,对于数组结构的数据来说,采用下标访问比较好。需要循环链表结构的数据时,一定不要使用普通for循环,这种做法很糟糕,数据量大的时候有可能会导致系统崩溃。
- java基础之foreach
- java基础----foreach
- java之foreach&Iterator
- Java之Foreach语句
- java web基础 --- forEach标签
- Java基础 foreach实现原理
- java之旅之foreach
- java实例之foreach语句
- Java语法糖之foreach
- Java语法糖之foreach
- java学习之Enumeration foreach
- JSP 基础之 JSTL <c:forEach>用法
- JSP 基础之 JSTL <c:forEach>用法
- JSP 基础之 JSTL <c:forEach>用法
- JSP 基础之 JSTL <c:forEach>用法
- JSP 基础之 JSTL <c:forEach>用法
- Java基础应用之循环控制(foreach循环优于for循环)
- Java基础8:Iterator和foreach循环
- 深入研究Servlet线程安全性问题
- 嵌入AppBar并且带搜索建议的搜索框(Android)
- JAVA源码笔记(jdk 1.7.0_75)--Thread-详细版本
- 希尔排序
- Android Studio使用新的Gradle构建工具配置NDK环境(二)
- java基础之foreach
- 初始化servlet中的两个init方法的区别
- snownlp 中文语法分析
- 1005. Spell It Right (20)
- leecode 解题总结:117. Populating Next Right Pointers in Each Node II
- android 将图片压缩到指定的大小
- (Mysql 六)事务
- 在Servlet的GenericServlet类中为什么有两个init()方法
- Android开发——SD卡_扫描SD卡中视频、音频文件