Wie übergebe ich eine ArrayList an einen varargs-Methodenparameter?

235

Grundsätzlich habe ich eine ArrayList von Standorten:

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

darunter nenne ich folgende Methode:

.getMap();

Die Parameter in der Methode getMap () sind:

getMap(WorldLocation... locations)

Das Problem, das ich habe, ist, dass ich nicht sicher bin, wie ich die GANZE Liste locationsdieser Methode weitergeben soll.

ich habe es versucht

.getMap(locations.toArray())

getMap akzeptiert dies jedoch nicht, da es keine Objekte [] akzeptiert.

Nun, wenn ich benutze

.getMap(locations.get(0));

es wird perfekt funktionieren ... aber ich muss irgendwie ALLE Speicherorte übergeben ... ich könnte natürlich weiterhin hinzufügen locations.get(1), locations.get(2)usw., aber die Größe des Arrays variiert. Ich bin einfach nicht an das ganze Konzept eines gewöhntArrayList

Was wäre der einfachste Weg, dies zu tun? Ich habe das Gefühl, dass ich gerade nicht klar denke.

MJ93
quelle

Antworten:

338

Quellartikel : Übergeben einer Liste als Argument an eine vararg-Methode


Verwenden Sie die toArray(T[] arr)Methode.

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

(Funktioniert toArray(new WorldLocation[0])auch, aber Sie würden ohne Grund ein Array mit der Länge Null zuweisen.)


Hier ist ein vollständiges Beispiel:

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
quelle
1
Wie teuer wäre dieser Vorgang in Bezug auf Speicher und Geschwindigkeit?
Mindreader
Dies funktioniert nicht ohne Warnung, wenn weitere Vorlagen beteiligt sind. ZB erhalten someMethod(someList.toArray(new ArrayList<Something>[someList.size()]))Sie eine Warnung, die sehr ärgerlich ist, wenn die Funktion länger als ein paar Zeilen ist (weil Sie sie entweder für die gesamte Funktion unterdrücken können oder das Array in einem zusätzlichen Schritt erstellen und die Warnung für die von Ihnen verwendete Variable unterdrücken müssen Speichern Sie es.
Qw3ry
23
Anscheinend besteht der schnellste Ansatz darin, eine Größe von Null anstelle der Größe des Arrays anzugeben. Kurz gesagt, weil die Kompilierungszeitkonstante die Verwendung einer optimierten Methode ermöglicht. shipilev.net/blog/2016/arrays-wisdom-ancients
geg
2
@ JoshM. Java braucht viele Dinge. ;) Ich vermisse auch (aus einem C # -Hintergrund) Indexoperatoren. Die Arbeit mit Wörterbüchern ist in C # viel reibungsloser als die Arbeit mit HashMaps in Java.
Per Lundberg
@PerLundberg - stimme voll und ganz zu. Auch ein hauptsächlich C # -Entwickler, der derzeit mit Java8 arbeitet. Vielleicht ist 10/11 besser. :-P
Josh M.
42

In Java 8:

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

.getMap(locations.stream().toArray(WorldLocation[]::new));
jmhostalet
quelle
2
das ist java voodoo, aber besser java (8) voodoo .. danke!
GranadaCoder
locations.toArray(WorldLocations[]::new)scheint auch zu funktionieren seit Java 11 (ohne die .stream())
Eran Medan
12

Eine kürzere Version der akzeptierten Antwort mit Guava:

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

kann durch statischen Import in Array weiter verkürzt werden:

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

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

Du kannst tun:

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

oder

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

oder

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

@SuppressWarnings("unchecked") wird benötigt, um die ide-Warnung zu entfernen.

Imar
quelle
1
2. Lösung ist besser!
Gaurav