¿Cómo pasar una ArrayList a un parámetro del método varargs?

237

Básicamente tengo una ArrayList de ubicaciones:

ArrayList<WorldLocation> locations = new ArrayList<WorldLocation>();

debajo de esto llamo el siguiente método:

.getMap();

Los parámetros en el método getMap () son:

getMap(WorldLocation... locations)

El problema que tengo es que no estoy seguro de cómo pasar toda la lista de locationsese método.

He intentado

.getMap(locations.toArray())

pero getMap no acepta eso porque no acepta objetos [].

Ahora si uso

.getMap(locations.get(0));

funcionará perfectamente ... pero de alguna manera necesito pasar TODAS las ubicaciones ... Por supuesto, podría seguir agregando, locations.get(1), locations.get(2)etc., pero el tamaño de la matriz varía. Simplemente no estoy acostumbrado a todo el concepto de unArrayList

¿Cuál sería la forma más fácil de hacer esto? Siento que no estoy pensando bien en este momento.

MJ93
fuente

Respuestas:

341

Artículo de origen: pasar una lista como argumento a un método vararg


Usa el toArray(T[] arr)método.

.getMap(locations.toArray(new WorldLocation[locations.size()]))

( toArray(new WorldLocation[0])también funciona, pero asignaría una matriz de longitud cero sin ningún motivo).


Aquí hay un ejemplo completo:

public static void method(String... strs) {
    for (String s : strs)
        System.out.println(s);
}

...
    List<String> strs = new ArrayList<String>();
    strs.add("hello");
    strs.add("wordld");

    method(strs.toArray(new String[strs.size()]));
    //     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
...
aioobe
fuente
1
¿Qué tan costosa sería esta operación en términos de memoria y velocidad?
lector de mente
Esto no funcionará sin una advertencia si hay más plantillas involucradas. Por ejemplo, someMethod(someList.toArray(new ArrayList<Something>[someList.size()]))le dará una advertencia que es muy molesta si la función tiene más de unas pocas líneas (porque puede suprimirla para toda la función o debe crear la matriz en un paso adicional y suprimir la advertencia en la variable que almacenarlo.
Qw3ry
23
Aparentemente, el enfoque más rápido es dar un tamaño de cero en lugar del tamaño de la matriz. En resumen, es porque la constante de tiempo de compilación permite el uso de un método optimizado. shipilev.net/blog/2016/arrays-wisdom-ancients
geg
2
@JoshM. Java necesita muchas cosas. ;) También (proveniente de un fondo de C #) omito operadores de índice. Trabajar con diccionarios es mucho más sencillo en C # que trabajar con HashMaps en Java.
Según Lundberg el
@PerLundberg - Totalmente de acuerdo. También es un desarrollador principalmente de C # que actualmente trabaja con Java8. Quizás el 10/11 será mejor. :-P
Josh M.
42

En Java 8:

List<WorldLocation> locations = new ArrayList<>();

.getMap(locations.stream().toArray(WorldLocation[]::new));
jmhostalet
fuente
2
Esto es Java Voodoo, pero mejor Java (8) Voodoo ... ¡Gracias!
granadaCoder
locations.toArray(WorldLocations[]::new)también parece funcionar desde java 11 (Sin el .stream())
Eran Medan
12

Una versión más corta de la respuesta aceptada usando Guava:

.getMap(Iterables.toArray(locations, WorldLocation.class));

se puede acortar aún más importando estáticamente a la matriz:

import static com.google.common.collect.toArray;
// ...

    .getMap(toArray(locations, WorldLocation.class));
tkruse
fuente
1

Tu puedes hacer:

getMap(locations.toArray(new WorldLocation[locations.size()]));

o

getMap(locations.toArray(new WorldLocation[0]));

o

getMap(new WorldLocation[locations.size()]);

@SuppressWarnings("unchecked") es necesario para eliminar la advertencia ide.

Imar
fuente
1
¡La segunda solución es mejor!
Gaurav