List <item>比List更快吗?

时间:2016-12-20 03:38:56

标签: java performance list arraylist

我正在开发一个Java应用程序,其中包含许多List - s和过程,我需要它才能执行得非常快。我想知道何时指定列表的类型元素,如果循环更快。

一个例子:

代码1:

List list = new ArrayList();
Item item;
list.add(...);
list.add(...);
list.add(...);
int t = list.size();
for(int i = 0; i < t; i++){
    item = (Item)list.get(i);
    //...
}

代码2:

List<Item> list = new ArrayList<Item>();
Item item;
list.add(...);
list.add(...);
list.add(...);
int t = list.size();
for(int i = 0; i < t; i++){
    item = list.get(i);
    //...
}

code 2code 1更快吗?

4 个答案:

答案 0 :(得分:4)

它们具有相同的运行时性能,因为Java Generics是使用类型擦除实现的。以下描述来自Java Generics的Oracle / Sun教程

https://docs.oracle.com/javase/tutorial/java/generics/erasure.html

  

类型删除

     

...

     

类型擦除确保不会为参数化创建新类   类型;因此,泛型不会产生运行时开销

答案 1 :(得分:4)

它们将具有完全相同的性能,因为它们编译为完全相同的代码。这就是type erasure的工作原理:它会移除List<Foo> List Foo foo = list.get(i),并用Foo foo = (Foo) list.get(i)替换instanceof List<Foo>(以及类似的调用)。这就是为什么,例如,您无法询问某些内容是否为<Foo> - 运行时缺少public class Test { public void raw() { String s; List list = new ArrayList(); for (int i = 0, t = list.size(); i < t; i++) { s = (String) list.get(i); } } public void generic() { String s; List<String> list = new ArrayList<>(); for (int i = 0, t = list.size(); i < t; i++) { s = list.get(i); } } } 信息,因为它在编译时被删除了。

您可以自己验证。如果你选择一个简单的课程,比如:

javap -c Test

您可以编译它,然后使用Code: 0: new #2 // class java/util/ArrayList 3: dup 4: invokespecial #3 // Method java/util/ArrayList."<init>":()V 7: astore_2 8: iconst_0 9: istore_3 10: aload_2 11: invokeinterface #4, 1 // InterfaceMethod java/util/List.size:()I 16: istore 4 18: iload_3 19: iload 4 21: if_icmpge 41 24: aload_2 25: iload_3 26: invokeinterface #5, 2 // InterfaceMethod java/util/List.get:(I)Ljava/lang/Object; 31: checkcast #6 // class java/lang/String 34: astore_1 35: iinc 3, 1 38: goto 18 41: return 对其进行反编译,并查看这两种方法。他们会是一样的。

(String)

特别注意第31字节的checkcast操作及其注释。那是<set xmlns:android="http://schemas.android.com/apk/res/android" android:interpolator="@android:anim/bounce_interpolator" > <alpha xmlns:android="http://schemas.android.com/apk/res/android" android:duration="500" android:fromAlpha="0.0" android:interpolator="@android:interpolator/decelerate_quad" android:toAlpha="1.0"/> </set> 演员。

答案 2 :(得分:2)

我希望这两个代码几乎完全相同。原因是您的代码的两个版本实际上都使用以下List

List<Object> list = new ArrayList<>();

在第一种情况下,Object是默认的集合类型,在第二种情况下,List<Item>在类型擦除后将变为List<Object>

答案 3 :(得分:0)

将这两个代码放在此程序中,您将自己看到结果:

 class Longest
 {
     public static void main(String[] args)
     {
            long start,end;

            start=System.currentTimeMillis();

            //Paste your above code here

            end=System.currentTimeMillis();

            System.out.println("Take taken by above code to execute:"+(end-start));
     }
   }