Java中的ArrayList或List声明

时间:2012-09-07 15:32:03

标签: java arraylist

这两个声明之间有什么区别?

声明1:

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

声明2:

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

10 个答案:

答案 0 :(得分:56)

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

在您将实现详细信息返回给客户端时隐藏实现详细信息的通用名称,稍后您可以透明地将实现从ArrayList更改为LinkedList

这种机制在您设计库等的情况下非常有用,这可能会在某些时候更改其实现细节,而客户端的更改很少。

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

这要求您始终需要返回ArrayList。在某些时候,如果您希望将实施细节更改为LinkedList,则客户端也应进行更改,以使用LinkedList代替ArrayList

答案 1 :(得分:11)

List是一个接口,ArrayList是List接口的实现。除了List接口中可用的方法之外,ArrayList类只有几个方法(i.e clone(), trimToSize(), removeRange() and ensureCapacity())。这没有太大区别。

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

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

我想说第一种方法是更好的方法,因为当你开发java应用程序时,当你应该将集合框架对象作为方法的参数传递时,那么最好采用第一种方法。

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

将来由于性能限制,如果要更改实现以使用LinkedList或其他实现List接口的类,而不是ArrayList,则需要在一点上进行更改only(实例化部分)。

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

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

答案 2 :(得分:6)

不同之处在于变体1强制您使用ArrayList,而变体2仅保证您拥有实现List<String>的任何内容。

稍后您可以毫不费力地将其更改为List<String> arrayList = new LinkedList<String>();。变体1可能要求您不仅要更改该行,还要更改其他部分,如果他们依赖于使用ArrayList<String>

因此,我几乎在任何情况下都使用List<String>,除非我需要调用ArrayList提供的其他方法(到目前为止从未如此):{{1} }和ensureCapacity(int)

答案 3 :(得分:2)

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

答案 4 :(得分:2)

很容易将实施更改为ListSet

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

答案 5 :(得分:2)

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

面向对象的方法基于模块化和可重用性,通过关注点分离 - 将结构与任何类型的对象一起使用的能力(只要它遵守一些规则)。

您可以实例化以下内容:

ArrayList list = new ArrayList();

而不是

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

通过声明和使用泛型类型,您将通知结构将管理的对象类型,例如,如果您在该结构中插入非法类型,编译器将能够通知您。让我们说:

// 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");

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

/**
 * 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(...));

从中得出的主要内容是您要指定要包装的对象类型。

至于使用Object l = new ArrayList<>();,您无法访问ListArrayList实施,因此您无法对该集合做太多工作。

答案 6 :(得分:1)

List是接口,ArrayList是实现的具体类。 始终建议使用。

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

因为这里列表参考是灵活的。它还可以保存LinkedList or Vector对象。

答案 7 :(得分:1)

在某些情况下,您可能更喜欢第一个(略微)提高性能,例如在某些JVM without a JIT compiler上。

在这种非常具体的背景下,你应该使用第一个。

答案 8 :(得分:1)

您可以参考此链接 http://docs.oracle.com/javase/6/docs/api/java/util/List.html

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

答案 9 :(得分:0)

每当您看到像Guava这样的开源社区和Google Developer(Android库)的编码时,他们就会使用这种方法

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

因为它隐藏了用户的实现细节。 你准确

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

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

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

供参考: Effective Java 2nd Edition:Item 52:通过接口引用对象