Angenommen, wir haben einen Collection<Foo>
. Was ist der beste (im aktuellen Kontext kürzeste) Weg, um ihn in Foo[]
umzuwandeln? Beliebige bekannte Bibliotheken sind erlaubt.
UPD: (ein weiterer Fall in diesem Abschnitt; hinterlassen Sie Kommentare, wenn Sie der Meinung sind, dass ein weiterer Thread dafür erstellt werden muss): Was ist mit der Umwandlung von Collection<Foo>
in Bar[]
, wobei Bar
einen Konstruktor mit einem Parameter des Typs Foo
hat, d. H. public Bar(Foo foo){ ... }
?
Wo x
die Sammlung ist:
Foo[] foos = x.toArray(new Foo[x.size()]);
Alternative Lösung zur aktualisierten Frage mit Java 8:
Bar[] result = foos.stream()
.map(x -> new Bar(x))
.toArray(size -> new Bar[size]);
Wenn Sie es mehrfach oder in einer Schleife verwenden, können Sie eine Konstante definieren
public static final Foo[] FOO = new Foo[]{};
und mache die Konvertierung gern
Foo[] foos = fooCollection.toArray(FOO);
Die toArray
-Methode ermittelt anhand des leeren Arrays den korrekten Typ des Zielarrays und erstellt ein neues Array für Sie.
Hier ist mein Vorschlag für das Update:
Collection<Foo> foos = new ArrayList<Foo>();
Collection<Bar> temp = new ArrayList<Bar>();
for (Foo foo:foos)
temp.add(new Bar(foo));
Bar[] bars = temp.toArray(new Bar[]{});
Wenn Sie Guava in Ihrem Projekt verwenden, können Sie Iterables::toArray
verwenden.
_Foo[] foos = Iterables.toArray(x, Foo.class);
_
Mit JDK/11 kann eine alternative Möglichkeit zum Konvertieren eines Collection<Foo>
in einen Foo[]
die Verwendung von Collection.toArray(IntFunction<T[]> generator)
wie folgt sein:
Foo[] foos = fooCollection.toArray(new Foo[0]); // before JDK 11
Foo[] updatedFoos = fooCollection.toArray(Foo[]::new); // after JDK 11
Wie von @Stuart in der Mailingliste (Hervorhebung meines) erläutert, sollte die Leistung im Wesentlichen dieselbe sein wie die der vorhandenen Collection.toArray(new T[0])
-
Das Ergebnis ist, dass Implementierungen, die
Arrays.copyOf(
) verwenden, die .__ sind. am schnellsten, wahrscheinlich weil es ist eine intrinsische.Es kann vermeiden, das frisch zugewiesene Array mit Nullen zu füllen, da es die .__ kennt. Der gesamte Array-Inhalt wird überschrieben. Dies gilt unabhängig davon, was die öffentliche API sieht aus wie.
Die Implementierung der API innerhalb des JDK lautet:
default <T> T[] toArray(IntFunction<T[]> generator) {
return toArray(generator.apply(0));
}
Die Standardimplementierung ruft
generator.apply(0)
auf, um ein Array mit der Länge null abzurufen und ruft einfachtoArray(T[])
auf. Dies geht durch dieArrays.copyOf()
schneller Weg, also im Wesentlichen dieselbe Geschwindigkeit wietoArray(new T[0])
.
Hinweis: - Nur dass die API-Verwendung zusammen mit einem Rückwärtsinkompatibilität geführt wird, wenn sie für Code mit null
-Werten verwendet wird, z. toArray(null)
, da diese Aufrufe aufgrund der vorhandenen toArray(T[] a)
jetzt mehrdeutig sind und nicht kompiliert werden können.
Hier ist die endgültige Lösung für den Fall im Update-Bereich (mithilfe von Google Collections):
Collections2.transform (fooCollection, new Function<Foo, Bar>() {
public Bar apply (Foo foo) {
return new Bar (foo);
}
}).toArray (new Bar[fooCollection.size()]);
Aber der Schlüsselansatz wurde hier in der Antwort von doublep erwähnt (ich habe die toArray
-Methode vergessen).
Zum Original siehe doublep answer:
Foo[] a = x.toArray(new Foo[x.size()]);
Wie für das Update:
int i = 0;
Bar[] bars = new Bar[fooCollection.size()];
for( Foo foo : fooCollection ) { // where fooCollection is Collection<Foo>
bars[i++] = new Bar(foo);
}
Sie haben beispielsweise eine Collection ArrayList mit Elementen der Student-Klasse:
List stuList = new ArrayList();
Student s1 = new Student("Raju");
Student s2 = new Student("Harish");
stuList.add(s1);
stuList.add(s2);
//now you can convert this collection stuList to Array like this
Object[] stuArr = stuList.toArray(); // <----- toArray() function will convert collection to array