Supposons que nous ayons un Collection<Foo>
. Quel est le meilleur moyen (le plus court en LoC dans le contexte actuel) de le transformer en Foo[]
? Toutes les bibliothèques notoires sont autorisées.
UPD: (encore un cas dans cette section; laissez des commentaires si vous pensez que cela vaut la peine de créer un autre fil de discussion pour lui): Qu'en est-il de la transformation de Collection<Foo>
en Bar[]
où Bar
a un constructeur avec 1 paramètre de type Foo
i.e. public Bar(Foo foo){ ... }
?
Où x
est la collection:
Foo[] foos = x.toArray(new Foo[x.size()]);
Solution alternative à la question mise à jour avec Java 8:
Bar[] result = foos.stream()
.map(x -> new Bar(x))
.toArray(size -> new Bar[size]);
Si vous l’utilisez plus d’une fois ou en boucle, vous pouvez définir une constante
public static final Foo[] FOO = new Foo[]{};
et faire la conversion comme
Foo[] foos = fooCollection.toArray(FOO);
La méthode toArray
utilisera le tableau vide pour déterminer le type correct du tableau cible et créer un nouveau tableau pour vous.
Voici ma proposition pour la mise à jour:
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[]{});
Si vous utilisez Guava dans votre projet, vous pouvez utiliser Iterables::toArray
.
_Foo[] foos = Iterables.toArray(x, Foo.class);
_
Avec JDK/11, un autre moyen de convertir un Collection<Foo>
en Foo[]
pourrait être d’utiliser Collection.toArray(IntFunction<T[]> generator)
en tant que:
Foo[] foos = fooCollection.toArray(new Foo[0]); // before JDK 11
Foo[] updatedFoos = fooCollection.toArray(Foo[]::new); // after JDK 11
Comme expliqué par @Stuart sur la liste de diffusion } (c'est nous qui soulignons), ses performances devraient être essentiellement les mêmes que celles de l'existant Collection.toArray(new T[0])
-
Le résultat est que les implémentations qui utilisent
Arrays.copyOf(
) sont les le plus rapide, probablement parce que c'est un intrinsèque.Il peut éviter de remplir à zéro le tableau fraîchement alloué car il connaît le fichier tout le contenu du tableau sera écrasé. Ceci est vrai indépendamment de quoi l'API publique ressemble.
L'implémentation de l'API dans le JDK se lit comme suit:
default <T> T[] toArray(IntFunction<T[]> generator) {
return toArray(generator.apply(0));
}
L'implémentation par défaut appelle
generator.apply(0)
pour obtenir un tableau de longueur nulle et appelle simplementtoArray(T[])
. Cela passe par laArrays.copyOf()
voie rapide, elle a donc sensiblement la même vitesse quetoArray(new T[0])
.
Note: - Simplement que l'utilisation de l'API doit être guidée par une incompatibilité descendante lorsqu'il est utilisé pour du code avec des valeurs null
, par exemple. toArray(null)
puisque ces appels seraient maintenant ambigus en raison de la fonction toArray(T[] a)
existante et ne pourraient pas être compilés.
Voici la solution finale pour le cas dans la section mise à jour (avec l'aide de Google Collections):
Collections2.transform (fooCollection, new Function<Foo, Bar>() {
public Bar apply (Foo foo) {
return new Bar (foo);
}
}).toArray (new Bar[fooCollection.size()]);
Mais l'approche clé ici a été mentionnée dans la réponse de doublep (j'ai oublié pour la méthode toArray
).
Pour l'original, voir doublep answer:
Foo[] a = x.toArray(new Foo[x.size()]);
En ce qui concerne la mise à jour:
int i = 0;
Bar[] bars = new Bar[fooCollection.size()];
for( Foo foo : fooCollection ) { // where fooCollection is Collection<Foo>
bars[i++] = new Bar(foo);
}
Par exemple, vous avez collection ArrayList avec des éléments de la classe Student:
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