Comment passer un ArrayList à un paramètre de méthode varargs?

237

Fondamentalement, j'ai une liste de tableaux d'emplacements:

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

ci-dessous j'appelle la méthode suivante:

.getMap();

les paramètres de la méthode getMap () sont:

getMap(WorldLocation... locations)

Le problème que j'ai, c'est que je ne sais pas comment passer la liste ENTIÈRE locationsdans cette méthode.

J'ai essayé

.getMap(locations.toArray())

mais getMap n'accepte pas cela car il n'accepte pas les objets [].

Maintenant, si j'utilise

.getMap(locations.get(0));

cela fonctionnera parfaitement ... mais je dois en quelque sorte passer dans TOUS les emplacements ... Je pourrais bien sûr continuer à ajouter locations.get(1), locations.get(2)etc., mais la taille du tableau varie. Je ne suis tout simplement pas habitué à tout le concept d'unArrayList

Quelle serait la façon la plus simple de procéder? J'ai l'impression de ne pas penser directement en ce moment.

MJ93
la source

Réponses:

341

Article source: Passer une liste comme argument à une méthode vararg


Utilisez la toArray(T[] arr)méthode.

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

( toArray(new WorldLocation[0])fonctionne également, mais vous alloueriez un tableau de longueur nulle sans raison.)


Voici un exemple complet:

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
la source
1
Quel serait le coût de cette opération en termes de mémoire et de vitesse?
mindreader
Cela ne fonctionnera pas sans avertissement si d'autres modèles sont impliqués. Par exemple someMethod(someList.toArray(new ArrayList<Something>[someList.size()])), vous obtiendrez un avertissement qui est très ennuyeux si la fonction fait plus de quelques lignes (car vous pouvez soit la supprimer pour toute la fonction, soit créer le tableau dans une étape supplémentaire et supprimer l'avertissement sur la variable que vous stocker.
Qw3ry
23
Apparemment, l'approche la plus rapide donne une taille de zéro plutôt que la taille du tableau. En bref, c'est parce que la constante de temps de compilation permet l'utilisation d'une méthode optimisée. shipilev.net/blog/2016/arrays-wisdom-ancients
geg
2
@JoshM. Java a besoin de beaucoup de choses. ;) Je manque également (venant d'un arrière-plan C #) les opérateurs d'index. Travailler avec des dictionnaires est beaucoup plus fluide en C # que de travailler avec HashMaps en Java.
Per Lundberg
@PerLundberg - Tout à fait d'accord. Également un développeur principalement C # travaillant actuellement avec Java8. Peut-être que 10/11 sera mieux. :-P
Josh M.
42

En Java 8:

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

.getMap(locations.stream().toArray(WorldLocation[]::new));
jmhostalet
la source
2
c'est du vaudou java, mais mieux du vaudou java (8) .. merci!
granadaCoder
locations.toArray(WorldLocations[]::new)semble également fonctionner depuis java 11 (sans le .stream())
Eran Medan
12

Une version plus courte de la réponse acceptée en utilisant la goyave:

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

peut être encore raccourci en important statiquement dans Array:

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

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

Tu peux faire:

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

ou

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

ou

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

@SuppressWarnings("unchecked") est nécessaire pour supprimer l'avertissement ide.

Imar
la source
1
La 2ème solution est meilleure!
gaurav