¿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.


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

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

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

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.


1
¡La segunda solución es mejor!
Gaurav
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.