说明:已发一类似贴,http://topic.csdn.net/u/20090529/17/69e63b93-a9db-4612-961b-c9c57c0ddfb4.html?seed=358121370,为能有更多人参与,再发一个标题好点的吧.
方法1: 
List <User> userList = getUserList(); 
for (User user : userList) 

    System.out.println(user.getUserid); 
} 方法2: 
List userList = (ArrayList)getUserList(); 
for (int i=0;i < userList.length; i++) 

    User user = (User)userList.get(i); 
    System.out.println(user.getUserid); 
} 请问以上那种方法效率更高呢?或者更好呢? 
注:之前我都是用后一种方法,对第一种总觉得不美观,没用它,后来我看了不少其它人代码,感觉很多人都喜欢用第一种,而自己也 
有点脱离大众的感觉啊,心里怪怪的,想改过来,但工作量要大,不改呢,要总觉得脱离主流,我测试过,感觉两者效率差不多(也许我数据 
量比较小吧,没看出来),要有点不想改了,可是用第2种编译器老是有警告提示,又很不爽,各位大侠对这两种方法谈谈看法吧,最好要有说服力的理由,谢了.

解决方案 »

  1.   

    兄弟,其实想测试一段程序的运行效率非常简单,
    在程序运行上一行加上:
    System.currentTimeMillis() 
    和程序运行后再加同样的
    System.currentTimeMillis() 
    这样可以算出程序是否最优.
    当然最好是循环一下,不然差别太小了.非常的明显,你的方法2 效率绝对是最低,因为每次循环完一次,都要去求这个List的大小,这是需要耗时间的!这个是最好的:
    List userList = (ArrayList)getUserList(); 
    for (int i=0, k = userList.length;i < k; i++) 

        User user = (User)userList.get(i); 
        System.out.println(user.getUserid); 

      

  2.   

    而且特别是List特别庞大的时候,我写的那种方法就越明显!!!
      

  3.   


    求这个List的大小不耗费时间吧?其实解释返回List里面的index属性
      

  4.   


    JDK支持范形就用第一种吧
      

  5.   

    JDK1.5的新特性foreach循环
    sun推出来的肯定比以前的循环好!
      

  6.   

    List <User> userList = getUserList(); 
    for (User user : userList) 

        System.out.println(user.getUserid); 
    } 这个效率高,不管是从执行的语句,还是判断,都比方法二高
      

  7.   

    我可以很明确的告诉你,效率是第二种方法最高!
    但是少量的数据的话,而且不需要用的当前遍历到的下标的话,用第一种方法比较方便,
    至于哪个说的第二种方法每次都要去一次List的长度很费时间的话,完全是谬论,
    看下JDK的源代码就知道,他在里面是用一个int型变量来保存的,每次只是简单的返回这个值,哪里效率低了为什么第一种效率低?
    因为那种形式在JDK解释的时候实际上是翻译成一下形式的:List <User> userList = getUserList();
    Iterator<User> iter = userList.iterator() ;
    while( iter.hasNext() ){
      User user = iter.next();
      //....这里才是你写的代码
    }
    而且在第二种形式里他还用到了同步(直接没看到),效率是要低些的。
    所以:

    根据自己的情况,数据较少,且在执行过程中不会进行当前遍历List的添加及删除操作,可以使用第一种,
    否则的话,就要使用第二种了。

      

  8.   

    //这里不是length,是getSize()方法,多谢提醒,随手写的,有点马虎,不好意思,不过,还真骗过了几双眼睛呀,呵.
    解释得很好,终于出现不同的声音了,关于效率方面,我认同你的解释,先不结贴吧,希望让有类似疑问的朋友也能参考下.
      

  9.   

    标记了 RandomAccess 接口的。第二种比第一种快。
    没标记的,第一种比第二种快。
      

  10.   

    for (int i=0,j=userList.length;i < j; i++) 

        User user = (User)userList.get(i); 
        System.out.println(user.getUserid); 
      

  11.   

    按qusic的说法,确实是第2种写法的效率比较高 !
    不过可以看看http://topic.csdn.net/u/20080929/13/3b236174-bc1d-4dee-9f54-05e7d49a6a2f.html
    以前有人讨论过的帖子
      

  12.   

    奥!我疏忽了,是size()方法,直接敲的代码,getter顺手了,呵呵~
      

  13.   

    存取对象map肯定比list效率高,map不适合存取大量对象,而list就适合,
    所以可将map和list结合使用!
      

  14.   

    JDK5.0以上支持泛型,应该是第一种
    第二种最后先求出LIST的大小,不然每次循环都要计算,很费时间的
      

  15.   

    不知道大家注意到另一个问题没用?
    在jdk5.0中引入了范型的概念,List <User> userList = getUserList(); 
    for (User user : userList) 

        System.out.println(user.getUserid); 
    } 这种形式省去了类的强制转换,性能应该是有提高的。
    另一方面,方式1具有更好的灵活性,对于userList不管你是list,还是其他collection照单全收如果是jdk1.5建议采用方式1。
      

  16.   


    public class EffectionTest 
    {

    public static void main(String[] args) 
    {
    List<User> users = new ArrayList<User>();
    int size = 10000000;
    for(int i = 0; i < size; ++ i)
    {
    User user = new User();
    user.id = i;
    users.add(user);
    }

    long beginTime = System.nanoTime();
    /*for(User user : users)
    {
    System.out.println(user.getId());
    }*/

    for(int i = 0; i < users.size(); ++ i)
    {
    User user = users.get(i);
    System.out.println(user.getId());
    }
    long endTime = System.nanoTime();
    System.out.println("The result is : " + (endTime - beginTime));

    }
    }class User 
    {
    int id;

    public int getId() {
    return this.id;
    }
    }我测试了一下:
    数据达到10000000条时
    第一种耗时:87.577秒
    第二种耗时:79.870秒
    试验是检验真理的唯一标准,看来第二种效率高,不过数据量小的时候,看不出差别,反正1,000,000条的时候没有什么区别,上10,000,000条时,差别就大了。
      

  17.   

    确实是第二种效率高,第一种在编译时其实是用了Iterator的遍历,Iterator是需要考虑同步的。
      

  18.   

    java效率要低点,c好些;算法第二种好些
      

  19.   

    http://www.baidu.com
      

  20.   

    Exception in thread "main" java.lang.OutOfMemoryError: Java heap space
    at test.EffectionTest.main(EffectionTest.java:15)
    ???????我测试了一下,测不了呢
      

  21.   

    再次测试
    int size = 1000000;
    1--The result is : 11082358791
    2--The result is : 11681350284
    第一个有哪么一点点优势,不知测得准不,
    (MyEclipse6.5+JDK6.0)
      

  22.   

    List userList = (ArrayList)getUserList(); 
    for (int i=0, k = userList.length;i < k; i++) 

        User user = (User)userList.get(i); 
        System.out.println(user.getUserid); 
      

  23.   

    我觉得第一种效率低了许多,
    List userList = (ArrayList)getUserList(); 
    for (int i=0, k = userList.length;i < k; i++) 

        User user = (User)userList.get(i); 
        System.out.println(user.getUserid); 
    }
    用这个可行性比较好,提高了很多
    http://lhc303.com留个脚印
      

  24.   

    貌似差别不大,平时习惯用泛型,需要下标时采用get(int index);
      

  25.   


    private static void test3(){

    Date date=null;

    List<test> tests=new ArrayList<test>();
    for(int i=0;i<1000000;i++){
    tests.add(new test());
    }
    date=new Date();
    System.out.println(date.getTime());
    for(test t:tests){
    }
    date=new Date();
    System.out.println(date.getTime());
    for(int i=0;i<tests.size();i++){
    }
    date=new Date();
    System.out.println(date.getTime());
    }
    /*
    执行结果:
    1243997882187
    1243997882265
    1243997882281
    */第一种foreach方式的用78mm,第二种用索引方式的只用了16mm看来第二种快
      

  26.   

    测试程序:
    public class TestUserFor { /**
     * @param args
     */
    public static void main(String[] args) {
    // TODO Auto-generated method stub
    List<UserInfor> list = new ArrayList<UserInfor>();
    UserInfor user = null;
    for (int i = 0; i < 80000; i++) {
    user = new UserInfor();
    user.setUserName("ii");
    list.add(user);
    }
    int size = list.size();
    UserInfor c1 = null;
    String name = "";
    long start = System.currentTimeMillis();
    for (int i = 0; i < size; i++) {
    c1 = list.get(i);
    name = c1.getUserName();
    }
    long end = System.currentTimeMillis() - start;
    System.out.println("1000000个数据:");
    System.out.println("1. for + get(i)方法: " + end); start = System.currentTimeMillis();
    for (UserInfor c2 : list) {
    name = c2.getUserName();
    }
    end = System.currentTimeMillis() - start;
    System.out.println("2. for(:)方法:" + end);
    }}
    测试结果:
    1. 80000个数据
     for + get(i)方法: 0毫秒
     for(:)方法:0毫秒
    2. 90000个数据
     for + get(i)方法: 0毫秒
     for(:)方法:16毫秒
    3. 1000000个数据
     for + get(i)方法: 31毫秒
     for(:)方法:63毫秒
    4. 2000000个数据
     for + get(i)方法: 47毫秒
     for(:)方法:141毫秒
    5. 3000000个数据
     for + get(i)方法: 79毫秒
     for(:)方法:187毫秒
    综上所测结果可以得出,for + get(i)的方法执行数据较快
    但是,在少量数据的时候,两者的差别不大,只有大量的数据时才体现出来。
    1000000个数据时for+get(i)的方法比for(:)的方法快两倍,2000000个数据时快3倍,但是在3000000个数据又回到2倍。
    由此可见,for + get(i)要快些,但是快多少,其变化成抛物线形式,有个峰值。
      

  27.   

    经最终测试:
    3308572(不发生内存溢出的最大值)个数据时:
    for + get(i)方法: 78毫秒 
    for(:)方法:859毫秒
    for + get(i)方法比for(:)的数据超过了10倍,很惊人。
    这个数据证明我先说的抛物线的说法不完全正确,在接近内存溢出的数据量时,体现了
    for + get(i)方法的绝对优势。
    具体原因暂不知晓,希望高手指点。
      

  28.   

    给大家用Java写一个好玩的Hello world !!!
    无意间发现在Java还有这个 ... 是可以用的。public class HelloWorld { public static void main(String... args) {
    hello();
    hello("Tomcat");
    hello("Tomcat","WebLogic");
    hello("Tomcat","WebLogic","WebSphere");
    } public static void hello(String... strs) {
    System.out.println("----------Start----------");
    for (String str : strs) {
    System.out.println("Hello "+str+"!!!");
    }
    System.out.println("----------End----------");
    }
    }
      

  29.   

    ArrayList的性能是最高的,但泛型应该比FOR循环效率高一些
      

  30.   

    我想根据List的实现不同,效率会有所区别。LinkedList和ArrayList的区别还是比较明显的。 ArrayList随机读取速度快,但是随机存取的话,效率就肯定不如LinkedList;而LinkedList则相反。针对上面的问题,我觉得如果是LinkedList,一二可能差不多;如果是ArrayList,二更快些。
      

  31.   

    package jefftan;import java.util.ArrayList;
    import java.util.Iterator;
    import java.util.List;public class Test { /**
     * @param args
     */
    public static void main(String[] args) { List <String> userList = getList();
    long nowtime = System.currentTimeMillis();
    for (String ss : userList)
    {
        // do noting;

    System.out.println((System.currentTimeMillis() -nowtime)+"ms");

    userList = getList();
    nowtime = System.currentTimeMillis();
    for (int i=0 ;i < userList.size(); i++)
    {
        userList.get(i);
        // do noting;
    }
    System.out.println((System.currentTimeMillis() -nowtime)+"ms");



    userList = getList();
    nowtime = System.currentTimeMillis();
    Iterator it = userList.iterator();
    while(it.hasNext()){
        it.next();
        // do noting;
    }
    System.out.println((System.currentTimeMillis() -nowtime)+"ms");
    }
    public static List<String> getList(){
    ArrayList<String> list = new ArrayList<String>();
    for(int i = 0; i < 1000000; i ++){
    list.add(null);
    }
    return list;
    }
    }结果:
    32ms
    16ms
    31ms
    PS:
    不打印,因为打印占了主要时间,测试不出来。
      

  32.   

    如果是LinkedList等用连表实现的collection
    请不要用userList.get(i); 
      

  33.   

    JDK 1.6之后才有的第一种for循环
      

  34.   

    第一种的for循环貌似有些颠覆标准编程语言的趋势..