2009-04-07 8 views
6

Si tiene una instancia de una colección, diga algo como:¿Qué pasar al método de instancia Array al método Array (T [] a)?

Collection<String> addresses = new ArrayList<String>(); 

que iban a ser poblada entonces con un grupo de valores, que es el "mejor", en su caso, hacer uso de la método toArray() sin requerir un tipo de conversión?

String[] addressesArray = addresses.toArray(new String[] {}); 
String[] addressesArray = addresses.toArray(new String[0]); 
String[] addressesArray = addresses.toArray(new String[addresses.size()]); 
String[] addressesArray = addresses.toArray(new String[addresses.size() + 5]); 

¿Hay alguna diferencia semántica entre las dos primeras? Es el tercero más eficiente? ¿El cuarto es menos eficiente que el tercero?

Respuesta

7

Según a findbugs report, este es el más eficiente:

String[] addressesArray = addresses.toArray(new String[addresses.size()]); 

Los creo;)

+2

Esto es incorrecto, de acuerdo con un artículo de @AlekseyShipilev http://shipilev.net/blog/2016/arrays-wisdom-ancients/ –

0

Esto se documenta en javadoc de la List interfaz:

Si la lista se ajusta en la matriz especificada con espacio de sobra (es decir, la matriz tiene más elementos que la lista), el elemento de la matriz inmediatamente después del final de la lista se establece en nulo. (Esto es útil para determinar la longitud de la lista sólo si la persona que llama sabe que la lista no contiene ningún elemento nulo.)

+0

Tiene sentido que si el tamaño de ArrayList es 5, y pasa a Array() una nueva matriz String de tamaño 10, entonces se redimensionará, pero aún no sé cuál es más o menos adecuada/eficiente . –

+0

No cambia el tamaño de la matriz, simplemente establece el elemento más allá del final de la lista para anular. –

0

Está haciendo efectivamente lo mismo con las dos primeras declaraciones.

El tercero es el más eficiente, porque si sus elementos no caben en la matriz, se crea una nueva matriz para usted.

3

Si eliges no creer en los demás, o simplemente quieres comprobarlo tú mismo, puedes revisar el source for java.util.ArrayList (publicar la fuente probablemente viola alguna licencia, me alegro de que solo esté enlazando). También obtiene una copia de todo el código fuente cuando descarga Sun's JDK).

Después de revisar el código fuente de <T> T[] toArray(T[] a); es evidente que:

String[] addressesArray = addresses.toArray(new String[addresses.size()]); 

es la forma más rápida de hacerlo.

Obviamente no siempre se puede tomar el tiempo para leer y comprender el código fuente, y algunas veces la mejor opción no siempre es obvia, pero para los métodos más simples, puede ser muy informativo leer la fuente.

5

Para mi dinero

String[] addressesArray = addresses.toArray(new String[0]); 

es más simple, menos propenso a errores y por lo tanto "mejor". También tiene la ventaja de que el mismo código funciona para colecciones simultáneas/sincronizadas. Tendría que estar en un código muy bajo, muy utilizado para la diferencia de rendimiento insignificante para hacer cualquier diferencia.

A menudo ve una matriz vacía asignada a static final para evitar la asignación en cada ejecución. Aparentemente, el rendimiento puede caer debido a esa "optimización" (la asignación realmente es muy rápida).

Actualización: Resulta que esto es más rápido que usar una matriz de tamaño.http://shipilev.net/blog/2016/arrays-wisdom-ancients/tl; dr: El reflejo es del tipo trivial que no implica la búsqueda lenta de métodos, y la reducción a cero de la matriz se puede descartar si se puede determinar que todos los elementos se escribirán (o la matriz no podrá alcanzarse).

+2

+1 para notar el problema de concurrencia. Me enfrenté a ese problema en mi código una vez: http://github.com/orfjackal/dimdwarf/blob/0d1a0897821a4e0e557a1390a7252a8580d2ec95/dimdwarf-core/src/main/java/net/orfjackal/dimdwarf/scheduler/TaskThreadPool.java#L111 -116 –

+0

Aunque normalmente utilizo el enfoque "addresses.toArray (new String [addresses.size()])". –

+1

¡Esto es más simple Y más rápido! http://shipilev.net/blog/2016/arrays-wisdom-ancients/ –

1

Esto es sobre todo un interés teórico, pero si la lista está vacía menudo, puede volver a utilizar una matriz de longitud cero:

private static final String[] EMPTY_STRING_ARRAY = {}; 
... 
String[] addressesArray = addresses.toArray(EMPTY_STRING_ARRAY); 

Desde matrices de longitud cero son inmutables (a diferencia de las matrices no de longitud cero), están BIEN almacenados y reutilizados.

+0

Ver la respuesta de Tom Hawtin. –

Cuestiones relacionadas