Java中的ArrayList或List声明

这两个声明有什么区别?

宣言1:

ArrayList<String> arrayList = new ArrayList<String>(); 

声明2:

 List<String> arrayList = new ArrayList<String>(); 
 List<String> arrayList = new ArrayList<String>(); 

是通用的,你想隐藏实现细节,而将其返回给客户端,在稍后的时间点,你可以透明地将实现从ArrayList更改为LinkedList

这种机制在devise库等的情况下非常有用,这些库可能会在某个时间点更改其实现细节,而客户端的修改很less。

 ArrayList<String> arrayList = new ArrayList<String>(); 

这要求你总是需要返回ArrayList 。 在某个时间点,如果您想要将实现细节更改为LinkedList ,则客户端的更改也应该使用LinkedList而不是ArrayList

List是一个接口,而ArrayList是List接口的一个实现。 除了List接口中可用的方法之外, ArrayList类只有几个方法(ie clone(), trimToSize(), removeRange() and ensureCapacity()) 。 这个差别不大。

  1. List<String> l = new ArrayList<>(); 2. ArrayList<String> l = new ArrayList<>(); 

如果使用第一个,您将能够调用List接口中可用的方法,并且不能调用ArrayList类中可用的新方法。 在那里,如果你使用第二个,你可以自由地使用ArrayList中的所有可用方法。

我会说,第一种方法是更好的方法,因为当你正在开发Java应用程序,当你应该将集合框架对象作为parameter passing给方法时,最好采用第一种方法。

 List<String> l = new ArrayList<>(); doSomething(l); 

将来由于性能的限制,如果你正在改变实现来使用LinkedList或者其他一些实现List接口的类,而不是ArrayList ,你只需要改变一点(实例化部分)。

 List<String> l = new LinkedList<>(); 

否则,你应该改变所有的地方,无论你在哪里使用特定的类实现作为方法参数。

不同之处在于变体1迫使你使用ArrayList而变体2只保证你有任何实现List<String>

稍后,您可以将其更改为List<String> arrayList = new LinkedList<String>(); 没有太多的麻烦。 变种1可能会要求您不仅要更改该行,还要更改其他部分,以及如果他们依赖于使用ArrayList<String>

因此,几乎在任何情况下,我都会使用List<String> ,除非需要调用ArrayList提供的其他方法(迄今为止从未如此): ensureCapacity(int)trimToSize()

第一个声明必须是一个ArrayList,第二个声明可以很容易地更改为另一个Listtypes。 因此,第二个是首选,因为它明确表示你不需要特定的实现。 (有时你确实需要一个实现,但是这很less见)

基本上它允许Java在一个结构实现中通过genericstypes声明(如class MyStructure<T extends TT> )存储多种types的对象,这是Java的主要特性之一。

面向对象的方法以模块化和可重用性为基础,通过分离关注点 – 使用具有任何types对象的结构(只要服从几条规则)的能力。

你可以实例化的东西如下:

 ArrayList list = new ArrayList(); 

代替

 ArrayList<String> list = new ArrayList<>(); 

例如,通过声明和使用genericstypes,您将通知它将pipe理的对象types的结构,例如,如果您将非法types插入到该结构中,编译器将能够通知您。 我们说:

 // this works List list1 = new ArrayList(); list1.add(1); list1.add("one"); // does not work List<String> list2 = new ArrayList<>(); list2.add(1); // compiler error here list2.add("one"); 

如果您想查看一些示例,请查看文档文档 :

 /** * Generic version of the Box class. * @param <T> the type of the value being boxed */ public class Box<T> { // T stands for "Type" private T t; public void set(T t) { this.t = t; } public T get() { return t; } } 

那么你可以实例化的东西,如:

 class Paper { ... } class Tissue { ... } // ... Box<Paper> boxOfPaper = new Box<>(); boxOfPaper.set(new Paper(...)); Box<Tissue> boxOfTissues = new Box<>(); boxOfTissues.set(new Tissue(...)); 

从中得出的主要原因是你正在指定你想要的对象types。

至于使用Object l = new ArrayList<>(); ,你没有访问ListArrayList实现,所以你将无法做很多的收集。

很容易将实现更改为List to Set

 Collection<String> stringList = new ArrayList<String>(); //Client side stringList = new LinkedList<String>(); stringList = new HashSet<String>(); //stringList = new HashSet<>(); java 1.7 and 1.8 

在某些情况下,您可能更喜欢第一个(稍微)提高性能,例如在某些没有JIT编译器的 JVM上。

出于这种非常具体的情况,你应该使用第一个。

可能你可以参考这个链接http://docs.oracle.com/javase/6/docs/api/java/util/List.html

List是一个接口.ArrayList,LinkedList等是实现列表的类。当你使用List接口的时候,你必须使用ListIterator迭代元素,并且可以向前和向后移动,在List中和ArrayList一样使用Iterator迭代其元素可以访问单向的方式。

List是接口,ArrayList是实现的具体类。 总是推荐使用。

 List<String> arrayList = new ArrayList<String>(); 

因为这里列表参考是灵活的。 它也可以容纳LinkedList or Vector对象。

每当你看到像Guava这样的开源社区和谷歌开发者(Android Library)的代码时,他们就使用这种方法

 List<String> strings = new ArrayList<String>(); 

因为它隐藏了用户的实现细节。 你正好

 List<String> strings = new ArrayList<String>(); 

这是通用的方法和这种专门的方法

 ArrayList<String> strings = new ArrayList<String>(); 

参考:有效的Java第二版:项目52:通过接口引用对象