2010-05-16 20 views
25

mi punto de vista, las ventajas de una lista de más de una matriz son bastante obvias:Beneficios de matrices

  • genéricos proporcionan tipificación más precisa: List<Integer>, List<? extends Number>, List<? super Integer>.
  • Una interfaz de lista tiene varios métodos útiles: addAll, remove etc. Mientras que para las matrices todas las operaciones estándar excepto get/set se deben realizar de una manera de procedimiento pasando a un método estático.
  • Las colecciones ofrecen implementaciones diferentes como ArrayList, LinkedList, listas no modificables y sincronizadas, que se pueden ocultar bajo una interfaz de lista común.
  • control de longitud OOB.

Como desventajas solo puedo mencionar la ausencia de azúcar sintáctico y una verificación del tipo de tiempo de ejecución. Al mismo tiempo, el soporte de ambas estructuras requiere el uso frecuente de los métodos asList y toArray, lo que hace que el código sea menos legible. Entonces, tengo curiosidad por saber si hay algún beneficio importante de usar arreglos que extraño.

Respuesta

17

Las matrices son más eficientes, tanto en términos de tiempo de proceso como de espacio de memoria. Esto se aplica particularmente si está operando en tipos primitivos, como int o long, ya que List requiere que todos los elementos se envuelvan en un Object (como Integer o Long). Si bien las funciones de autoboxing introducidas por Java 5 reducen la cantidad de código que necesita para dicho ajuste y desempaquetado, no elimina los problemas de rendimiento, ya que los objetos de envoltura aún se están creando.

Sin embargo, la mayoría de las aplicaciones probablemente no tengan ningún cuello de botella de rendimiento relacionado con estos problemas, por lo que en la mayoría de los casos, List y otras colecciones deberían funcionar bien. En estos casos, la facilidad de programación supera el aumento en la memoria o el uso de la CPU, y List es la elección correcta.

+4

+1: las matrices son más eficientes, pero generalmente no las necesita. En todas las aplicaciones comerciales que he escrito, nunca hubo un problema de rendimiento que pudiera resolverse reemplazando colecciones con matrices. Solo en el número de herramientas de crujido he visto la necesidad de evitar envolver primitivas y, por lo tanto, la necesidad de seguir con las matrices. –

+0

@Christian: De acuerdo, en la mayoría de las situaciones las colecciones funcionan bien. – markusk

+0

Un gran defecto de los genéricos de Java es la falta de soporte para primitivos. Al menos algunas bibliotecas de terceros implementan clases de recolección para tipos primitivos, lo que elimina al menos la sobrecarga del boxeo y el desempaquetado. – josefx

4

Velocidad. Las colecciones son algo más lentas que las matrices simples: internamente, la mayoría todavía usan matrices, pero tienen capas adicionales de código alrededor de ellas. Por supuesto, a menos que tenga una necesidad específica de rendimiento adicional, aún debe usar colecciones.

Otra pequeña ventaja de las matrices es que podría ser más fácil llamar a los métodos variadic con las matrices. Sin embargo, esta nunca debería ser una razón principal para elegir una sobre otra.

10

Si su lista no cambia a menudo, las listas añaden mucho peso extra al objeto que nunca usará. Cuando intenta ejecutar algo que debe optimizarse, esto es útil. Este peso extra también hace que las cosas sean más lentas de lo que serían con solo arreglos. Sin embargo, a menos que sepa que necesita las ganancias que las matrices le brindan, debería simplemente usar Listas.

+1

Supongo que esto podría resumirse de la siguiente manera: Cuando necesite manipular un grupo de objetos claramente relacionados, use colecciones, de lo contrario use matrices. – Esko

2

Supongo que la respuesta teórica es que se supone que las matrices tienen un mejor rendimiento porque las colecciones genéricas tienen capas adicionales de abstracción. Personalmente, en una aplicación comercial, veo muy poco valor en el uso de matrices sobre colecciones genéricas.

6

Una cosa que no he visto mencionar aquí: las matrices pueden tener N dimensiones mientras que las listas están limitadas a una.Puede utilizar listas de listas, pero la sintaxis (List<List<...>>) es mucho más engorroso que [] []

1

matrices son mejores en las siguientes situaciones:

  • que sabe que va a trabajar con número fijo de elementos en la matriz
  • que no es necesario cambiar el tamaño de la matriz

las matrices son:

  • más rápido que cualquier colección

Colecciones similar a la matriz:

  • ArrayList - lectura rápida y añadir al final de la List. Utiliza una matriz interna. Lento si tiene que aumentar el tamaño del List
  • LinkedList - agregue rápidamente a ambos lados del List. Rápido aumento/disminución del tamaño dinámico. No usa internamente gama

Conclusión:

recomiendo utilizar el apropiado para su colección escenario. No luchar con Array [] porque el paquete Collections ofrece muy cómodo API como add(), etc. addAll()


Referencia: puede encontrar una comparación más detallada aquí ->"Arrays vs ArrayList vs LinkedList vs..."

2

Además de la otra respuestas, hay una propiedad sutil de matrices que se puede considerar una ventaja sobre las listas. Se puede ilustrar con el siguiente código:

//This works 
Integer[] ints = new Integer[4]; 
Number[] nums = ints; 
//This doesn't work 
List<Integer> intList = new ArrayList<Integer>(); 
List<Number> numList = intList; //Does not compile 
List<Number> numList2 = (List<Number>)intList; //Does not compile either 

Mientras que un conjunto de una subclase es una matriz de la superclase, las listas de las subclases no son listas de superclases (y hay una buena razón para ello - los genéricos tendrían un tipo de error de seguridad si estuviera permitido).

+1

Y, de hecho, las matrices tienen una falla de seguridad de tipo porque eso está permitido, pero la falla solo se detecta en tiempo de ejecución, no en tiempo de compilación. Podría seguir tu código con 'nums [0] = new Double (8.9)' y eso compilaría. Solo en el tiempo de ejecución arrojaría una excepción. –

+0

No puede almacenar ninguna instancia de la superclase en la matriz de subclase. Por lo tanto, una matriz de una subclase NO es una matriz de una superclase de acuerdo con el [Principio de sustitución de Liskov] (http://en.wikipedia.org/wiki/Liskov_substitution_principle). Pero esto solo se detecta en tiempo de ejecución, como señaló @ Daniel. –

+0

Por supuesto. Las limitaciones en el código genérico están destinadas a proteger contra la clase ClassCastException inesperada, mientras que las matrices no protegen contra ArrayStoreException. Pero desde el punto de vista del compilador, Integer [] IS a Number [], y se permite la conversión, suponiendo que el programador conoce el tipo de matriz real. –

3

Si hay algunos beneficios importantes de la utilización de matrices que echo de menos?

Acceso en tiempo real a cualquier elemento con una constante muy pequeña. Para acceder de forma segura a un elemento de matriz, solo se necesitan unas pocas instrucciones: un par de cargas, una comparación y una rama. La sucursal suele tener éxito casi el 100% del tiempo, por lo que el hardware moderno hace un excelente trabajo prediciéndolo.

+0

Me gustaría entender mejor las instrucciones que se mencionan aquí, ¿podría sugerir una fuente para que la revise? Gracias. – arin

0

Realmente depende de la situación. Las matrices son increíblemente rápidas, pero tienen un tamaño fijo y es posible que no sean adecuadas si la cantidad de datos que necesita procesar es muy grande. Las colecciones, por otro lado, tienen diversos grados de rendimiento, dependiendo de la subclase particular. ArrayList, por ejemplo, es principalmente un envoltorio alrededor de una matriz, por lo que debe tener requisitos similares de velocidad de iteración y memoria. En mi caso, normalmente utilizo la interfaz Iterable <T> siempre que sea posible, ya que brinda la mayor flexibilidad a mi código, permitiéndole procesar matrices residentes en memoria así como listas de datos que se obtienen de un archivo o de una red usando una clase iterable/iterator personalizada. Cuando llega el momento de crear una instancia real del objeto Iterable que paso, eso depende de la situación específica; si conozco el tamaño y encajará en la memoria de inmediato, entonces simplemente uso una matriz, mientras que si es posible que crezca, entonces usaré una ArrayList, y si necesita una inserción rápida en ambos extremos, entonces usaré una Lista enlazada.