2012-09-07 38 views
48

¿Cuál es la diferencia entre estas dos declaraciones?ArrayList o declaración de lista en Java

Declaración 1:

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

Declaración 2:

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

posible duplicado de [¿Por qué la codificación debe ser "a la interfaz" especialmente para los tipos de datos primitivos?] (http://stackoverflow.com/questions/9392813/why-the-coding-should-be-to-the-interface-especiallyfor -primitive- tipos de datos) – assylias

+0

Th es uno también: http://stackoverflow.com/questions/1413543/what-does-it-mean-to-program-to-a-interface – assylias

+0

Eche un vistazo a http://stackoverflow.com/questions/3383726/ java-declarando-desde-tipo-de-interfaz-en-lugar-de-clase – Maciej

Respuesta

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

es genérico en el que desea ocultar los detalles de implementación, mientras que devolverlo al cliente, en el punto de tarde es hora de que pueda cambiar la implementación de ArrayList a LinkedList de forma transparente.

Este mecanismo es útil en casos en los que diseña bibliotecas, etc., que pueden cambiar los detalles de implementación en algún momento con cambios mínimos en el lado del cliente.

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

Esto le obliga siempre necesidad de volver ArrayList. En algún punto del tiempo si desea cambiar los detalles de implementación al LinkedList, debe haber cambios en el lado del cliente también para usar LinkedList en lugar de ArrayList.

+2

Y no olvides que la clase Collections funciona completamente con la interfaz List, por lo que cosas como Collections.emptyList, Collections.synchronizedList Collections.unmodifiableList regresan a List. Entonces, si una API espera ArrayList, no tiene suerte si desea ajustar una lista existente con estos métodos. – Matt

+0

Para los parámetros _input_, seguro, estoy de acuerdo, pero esto es todo lo contrario; a saber, objeto _instantiation_. En este caso, lo único que hace es eliminar todas las funciones específicas de ArrayList que _deberían estar disponibles para usted. – Nyerguds

+0

"Esto indica que siempre debe devolver ArrayList" es completamente incorrecto, por cierto. De todos modos, puede hacer perfectamente su 'lista 'de tipo de devolución, sin importar lo que use internamente. – Nyerguds

1

La lista es la interfaz y ArrayList se implementa en la clase concreta. Siempre se recomienda usar.

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

Porque aquí la lista de referencia es flexible. También puede contener el objeto LinkedList or Vector.

6

La diferencia es que la variante 1 obliga a utilizar un ArrayList, mientras que la variante 2 solo garantiza que tiene algo que implemente List<String>.

Más adelante podría cambiar eso a List<String> arrayList = new LinkedList<String>(); sin mucha molestia. La variante 1 podría requerir que cambie no solo esa línea, sino también otras partes si confían en trabajar con un ArrayList<String>.

Así que haría uso de List<String> en casi cualquier caso, excepto cuando había necesidad de llamar a los métodos adicionales que ArrayList establece (que era nunca es el caso hasta ahora): ensureCapacity(int) y trimToSize().

2

La primera declaración debe ser una ArrayList, la segunda se puede cambiar fácilmente a otro tipo de lista. Como tal, se prefiere el segundo ya que deja en claro que no requiere una implementación específica. (A veces realmente necesita una implementación, pero eso es raro)

+0

Bueno, el segundo no se prefiere cuando la velocidad es el foco :-p 'invokeinterface' puede ser un poco más lento que' invokevirtual', que puede ser significativo en algunos contextos. – oldrinb

+1

Si el rendimiento es crítico, usaría una matriz. ;) –

1

Hay algunas situaciones en las que puede preferir la primera para (ligeramente) mejorar el rendimiento, por ejemplo, en algunas JVM without a JIT compiler.

Fuera de ese tipo de contexto muy específico, debe usar el primero.

1

Posiblemente puede hacer referencia a este enlace http://docs.oracle.com/javase/6/docs/api/java/util/List.html

lista es un interface.ArrayList, ListaEnlazada etc son clases que implementan la lista.Cuando utiliza List Interface, debe itearte elementos usando ListIterator y puede avanzar y retroceder, en la Lista donde se puede acceder de forma unidireccional como en ArrayList Iterar usando Iterator y sus elementos.

2

Es fácil cambiar la implementación de List a 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 
2

Básicamente se permite Java para almacenar varios tipos de objetos en una implementación estructura, mediante una declaración genérica de tipo (como class MyStructure<T extends TT>), que es una de las principales características de Javas.

Los enfoques orientados a objetos se basan en modularidad y reutilización por separación de preocupaciones: la capacidad de utilizar una estructura con cualquier tipo de objeto (siempre que obedezca unas pocas reglas).

Se podía crear una instancia de cosas como sigue:

ArrayList list = new ArrayList(); 

en lugar de

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

Al declarar y utilizar tipos genéricos que están informando a una estructura del tipo de objetos que gestionará y el compilador podrá informarle si está insertando un tipo ilegal en esa estructura, por ejemplo. Digamos:

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

Si quieres ver algunos ejemplos comprobar la documentación 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; } 
} 

Posteriormente, se podría crear una instancia de cosas como:

class Paper { ... } 
class Tissue { ... } 

// ... 
Box<Paper> boxOfPaper = new Box<>(); 
boxOfPaper.set(new Paper(...)); 

Box<Tissue> boxOfTissues = new Box<>(); 
boxOfTissues.set(new Tissue(...)); 

Lo principal a sacar de esta está especificando qué tipo de objeto desea encasillar.

En cuanto a usar Object l = new ArrayList<>();, no se está accediendo a la aplicación List o ArrayList por lo que no será capaz de hacer mucho con la colección.

9

List es una interfaz y ArrayList es una implementación de la interfaz de lista. La clase ArrayList tiene solo unos pocos métodos (i.e clone(), trimToSize(), removeRange() and ensureCapacity()) además de los métodos disponibles en la interfaz de la Lista. No hay mucha diferencia en esto.

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

Si se utiliza el primero, que será capaz de llamar a los métodos disponibles en la interfaz de la lista y no se puede hacer llamadas a los nuevos métodos disponibles en la clase ArrayList. En donde, puede usar todos los métodos disponibles en el ArrayList si usa el segundo.

Diría que el primer enfoque es mejor porque, cuando está desarrollando aplicaciones java, cuando se supone que debe pasar los objetos del marco de recopilación como argumentos a los métodos, entonces es mejor ir con el primer enfoque.

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

En el futuro debido a las limitaciones de rendimiento, si va a cambiar la aplicación a utilizar LinkedList o someother clases que implementan la interfaz List, en lugar de ArrayList, es necesario cambiar en un solo punto (la parte de instancias).

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

de lo contrario será supone que el cambio en todos los lugares, donde sea, que ha utilizado la implementación de la clase específica como argumentos del método.

+0

¿Puede explicar por qué el uso de la primera opción nos hace cambiar más que la línea de declaración? – TheLogicGuy

+0

¿Por qué la gente sigue propagando el argumento tonto de "puedes cambiarlo más tarde"? Si lo diseñas bien, siempre debería ser la excepción en lugar de la regla. El único efecto real aquí es que pierde todas las funciones disponibles en su 'ArrayList', excepto los conceptos básicos de' List'. – Nyerguds

0

Cada vez que usted ha visto la codificación de la comunidad de código abierto, como la guayaba y desde Google Developer (Biblioteca Android) que utilizan este enfoque

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

porque es ocultar el detalle de implementación de usuario. Es precisamente

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

Es la visión genérica y este enfoque especializado

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

Para Referencia: eficaz de Java 2ª Edición: Artículo 52: se refieren a objetos mediante sus interfaces