首先普通for循环是能获取元素下标,并能通过下标遍历元素,而增强for却不可以获取下标,因此在遍历时的效率不同。
当为数组时,效率几乎是差不多的
当为集合时效率却大不同,当为ArrayLIst时,普通for的效率高于增强for
当为LInkedList时,增强for的效率高于普通for
验证代码:
package com.niuguwang.jihe; import java.util.ArrayList; import java.util.Collection; import java.util.HashMap; import java.util.HashSet; import java.util.LinkedList; public class CollectionTest { public static void main(String[] args) { // ArrayList listtest =new ArrayList<>(); // LinkedList listtest =new LinkedList(); person[] listtest =new person[5000000]; for(int i=0;i<5000000;i++){ listtest[i]= new person("xiaoming"); } /* for(int i=0;i<5000000;i++){ listtest.add(new person("xiaoming")); } */ Object p=null; long start=System.currentTimeMillis(); for(int i=0;i<listtest.length;i++){ p=listtest[i]; } /* for(int i=0;i<(listtest.size());i++){ p = listtest.get(i); } */ System.out.println("普通for的耗用时间 "+(System.currentTimeMillis()-start)); long start1=System.currentTimeMillis(); for(Object o:listtest){ p=o; } System.out.println("增强for的耗用时间 "+(System.currentTimeMillis()-start1)); } } class person{ String name; public person(String name) { super(); this.name = name; } }
其次集合中的元素动态删除时,增强for无法动态删除,而普通for可以动态删除。在增强for动态删除时会报一个 java.util.ConcurrentModificationException的错误,而普通for却没有这个问题,但是每删除一个元素时,集合的size会发生变化,删除会有遗漏,所以建议使用迭代器Iterator对集合进行动态删除操作。
在next()方法中有一个checkForComodification()方法,其实现为:
final void checkForComodification() { if (modCount != expectedModCount) throw new ConcurrentModificationException(); }
可以看到,该函数是用来判断集合的修改次数是否合法。
在集合内部维护一个字段modCount用于记录集合被修改的次数,每当集合内部结构发生变化(add,remove,set)时,modCount+1。
在迭代器内部也维护一个字段expectedModCount,同样记录当前集合修改的次数,初始化为集合的modCount值。当我们在调用Iterator进行遍历操作时,如果有其他线程修改list会出现modCount!=expectedModCount的情况,就会报并发修改异常java.util.ConcurrentModificationException。
而使用迭代器删除时在执行remove操作时,同样先执行checkForComodification(),然后会执行ArrayList的remove()方法,该方法会将modCount值加1,这里我们将expectedModCount=modCount,使之保持统一。