web-dev-qa-db-fra.com

Le moyen le plus simple de transformer une collection en tableau?

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[]Bar a un constructeur avec 1 paramètre de type Foo i.e. public Bar(Foo foo){ ... }?

104
Roman

x est la collection:

Foo[] foos = x.toArray(new Foo[x.size()]);
233
doublep

Solution alternative à la question mise à jour avec Java 8:

Bar[] result = foos.stream()
    .map(x -> new Bar(x))
    .toArray(size -> new Bar[size]);
32
Jules

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[]{});
10
Andreas_D

Si vous utilisez Guava dans votre projet, vous pouvez utiliser Iterables::toArray .

_Foo[] foos = Iterables.toArray(x, Foo.class);
_
3
Andrea Bergonzo

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 simplement toArray(T[]). Cela passe par la Arrays.copyOf() voie rapide, elle a donc sensiblement la même vitesse que toArray(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.

3
nullpointer

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

3
Roman

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);
}    
2
OscarRyz

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
0
Jagadeesh HN