Il modo più semplice per trasformare la raccolta in array?

Supponiamo di avere una Collection . Qual è il modo migliore (il più breve in LoC nel contesto attuale) per trasformarlo in Foo[] ? Sono consentite tutte le librerie note .

UPD: (un altro caso in questa sezione, lascia i commenti se pensi che valga la pena di creare un altro thread per esso): Che ne dici di trasformare Collection in Bar[] dove Bar ha costruttore con 1 parametro di tipo Foo cioè public Bar(Foo foo){ ... } ?

Dove x è la raccolta:

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

Soluzione alternativa alla domanda aggiornata utilizzando Java 8:

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

Se lo usi più di una volta o in un ciclo, puoi definire una costante

 public static final Foo[] FOO = new Foo[]{}; 

e fai la conversione come

 Foo[] foos = fooCollection.toArray(FOO); 

Il metodo toArray utilizzerà l’array vuoto per determinare il tipo corretto dell’array di destinazione e creare un nuovo array per te.


Ecco la mia proposta per l’aggiornamento:

 Collection foos = new ArrayList(); Collection temp = new ArrayList(); for (Foo foo:foos) temp.add(new Bar(foo)); Bar[] bars = temp.toArray(new Bar[]{}); 

Ecco la soluzione finale per il caso nella sezione di aggiornamento (con l’aiuto di Google Collections):

 Collections2.transform (fooCollection, new Function() { public Bar apply (Foo foo) { return new Bar (foo); } }).toArray (new Bar[fooCollection.size()]); 

Ma l’approccio chiave qui è stato menzionato nella risposta del doublep (ho dimenticato il metodo toArray ).

Per l’originale vedi la risposta al doppio :

 Foo[] a = x.toArray(new Foo[x.size()]); 

Per quanto riguarda l’aggiornamento:

 int i = 0; Bar[] bars = new Bar[fooCollection.size()]; for( Foo foo : fooCollection ) { // where fooCollection is Collection bars[i++] = new Bar(foo); } 

Con JDK / 11, un modo alternativo di convertire una Collection in una Foo[] potrebbe essere quello di utilizzare Collection.toArray(IntFunction generator) come:

 Foo[] foos = fooCollection.toArray(new Foo[0]); // before JDK 11 Foo[] updatedFoos = fooCollection.toArray(Foo[]::new); // after JDK 11 

Come spiegato da @Stuart sulla mailing list (enfasi mia), le prestazioni di questo dovrebbero essere essenzialmente le stesse del Collection.toArray(new T[0]) esistente Collection.toArray(new T[0])

Il risultato è che le implementazioni che usano Arrays.copyOf( ) sono le più veloci, probabilmente perché sono intrinseche .

Può evitare di riempire lo zero dell’array appena assegnato perché sa che l’intero contenuto dell’array verrà sovrascritto. Questo è vero indipendentemente da come appare l’API pubblica.

L’implementazione dell’API all’interno di JDK è:

 default  T[] toArray(IntFunction generator) { return toArray(generator.apply(0)); } 

L’implementazione predefinita chiama generator.apply(0) per ottenere una matrice di lunghezza zero e quindi semplicemente chiama toArray(T[]) . Questo attraversa il percorso veloce Arrays.copyOf() , quindi è essenzialmente la stessa velocità di toArray(new T[0]) .


Nota : – Solo che l’uso dell’API deve essere guidato insieme a un’incompatibilità all’indietro quando viene utilizzato per il codice con valori null , ad esempio toArray(null) poiché queste chiamate sarebbero ora ambigue a causa di esistenti toArray(T[] a) e non riuscirebbero a compilare .