近跟foreach算是很有缘分吧,前同事跟我聊一个自己在网上看到的“ foreach使用过多会有性能问题,建议使用for i++来做遍历? ”我当时一听纳闷了,以前的时候看到文章说JVM对foreach语法糖是有做优化的,在很多博客也是推荐使用foreach的,为什么突然会有这么个说法呢,躺床上看到个博客 Java 性能优化的五大技巧 的第五点钟第2条中说“避免使用iterator()”,我决定试试究竟!

  执行时间(1000*1000数据量)
  ArrayLIst的遍历时间对比( 实验结果证明foreach要比for++要差那么些,但是非常接近 )
long start = System.currentTimeMillis();
for (int i = 0; i < list.size(); i ++) {
String s = list.get(i);
}
System.out.println("arrayList for i++ on 1000*1000 records time waste: " + (System.currentTimeMillis() - start));
start = System.currentTimeMillis();
for (String s : list) {
//
}
System.out.println("arrayList foreach on 1000*1000 records time waste: " + (System.currentTimeMillis() - start));
  执行结果:
  第1次:
  arrayList for i++ on 1000*1000 records time waste: 0
  arrayList foreach on 1000*1000 records time waste: 16
  第2次:
  arrayList for i++ on 1000*1000 records time waste: 0
  arrayList foreach on 1000*1000 records time waste: 0
  第3次:
  arrayList for i++ on 1000*1000 records time waste: 0
  arrayList foreach on 1000*1000 records time waste: 0
  LinkedLIst的遍历时间对比( 实验结果证明foreach要比for++好N多数量级倍,N具体多少取决于数据量 )
for (int i = 0; i < list.size(); i ++) {
String s = list.get(i);
}
System.out.println("LinkedList for i++ on 1000*1000 records time waste: " + (System.currentTimeMillis() - start));
start = System.currentTimeMillis();
for (String s : list) {
//
}
System.out.println("LinkedList foreach on 1000*1000 records time waste: " + (System.currentTimeMillis() - start));
  实验结果
  第一次:
  LinkedList for i++ on 1000*1000 records time waste: 41224
  LinkedList foreach on 1000*1000 records time waste: 11
  第二次:
  LinkedList for i++ on 1000*1000 records time waste: 43914
  LinkedList foreach on 1000*1000 records time waste: 11
  第三次:
  LinkedList for i++ on 1000*1000 records time waste: 57320
  LinkedList foreach on 1000*1000 records time waste: 16
  Array的遍历时间对比( 实验结果证明foreach要比for++要差那么些,但是非常接近,与ArrayList竟然那么相似 )
String[] array = (String[])list.toArray(new String[]{});
long start = System.currentTimeMillis();
for (int i = 0; i < array.length; i ++) {
String s = array[i];
}
System.out.println("Array for i++ on 1000*1000 records time waste: " + (System.currentTimeMillis() - start));
start = System.currentTimeMillis();
for (String s : array) {
//
}
System.out.println("Array foreach on 1000*1000 records time waste: " + (System.currentTimeMillis() - start));
  实验结果
  第一次:
  Array for i++ on 1000*1000 records time waste: 0
  Array foreach on 1000*1000 records time waste: 0
  第二次:
  Array for i++ on 1000*1000 records time waste: 0
  Array foreach on 1000*1000 records time waste: 16
  第三次:
  Array for i++ on 1000*1000 records time waste: 0
  Array foreach on 1000*1000 records time waste: 0
  foreach比for++费内存?
  先引用一位哥们的说法:
  every time you run into this loop, if strings is an Iterable, you will create a new Iterator instance. If you’re using an ArrayList, this is going to be allocating an object with 3 ints on your heap、浪费空间啊。
  关于耗费内存的说法我是支持的,但是” with 3 ints on your heap “这个我不能同意了,foreach语法糖实际是JVM根据对象生成一个迭代器,我们来看下源码,看下是不是多浪费了空间,浪费了多少空间,现以java.util.ArrayList为例:
public Iterator<E> iterator() {
return new Itr(); ////这部分是比for++多的
}
private class Itr implements Iterator<E> {
int cursor;       // index of next element to return
int lastRet = -1; // index of last element returned; -1 if no such
int expectedModCount = modCount;
public boolean hasNext() {
return cursor != size;
}
@SuppressWarnings("unchecked")
public E next() {
checkForComodification(); //这部分是比for++多的
int i = cursor;
if (i >= size)
throw new NoSuchElementException();
Object[] elementData = ArrayList.this.elementData;
if (i >= elementData.length)
throw new ConcurrentModificationException();
cursor = i + 1;
return (E) elementData[lastRet = i];
}
final void checkForComodification() {
if (modCount != expectedModCount)
throw new ConcurrentModificationException();
}
}
  由代码可见,foreach比for++多了new了一个对象,遍历的时候多了是否遍历种被修改判断,其余操作与for++是一致的。由此可见:多浪费空间一说是纯属扯蛋。
  总结
  1、foreach遍历线性集合对象比for++略低,但差距非常接近;
  2、foreach遍历链表集合对象比for++高的多,差距由集合对象数量决定
  3、foreach遍历内存使用上会比for++多那么一点点,迭代器实际返回的是集合的数据集;