2010-07-20 24 views
87

Supponiamo di avere un Collection<Foo>. Qual è il modo migliore (il più breve in LoC nel contesto corrente) per trasformarlo in Foo[]? Sono consentite tutte le librerie note .Il modo più semplice per trasformare la raccolta in array?

UPD: (un caso di più in questa sezione, lasciare commenti se si pensa che valga la pena di creare un altro thread per esso): Che dire di trasformare Collection<Foo>-Bar[] dove Bar ha costruttore con 1 parametro di tipo Foo cioè public Bar(Foo foo){ ... }?

risposta

205

Dove x è la raccolta:

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

** ** semplice (più facile), ma non migliore (memoria): 'x.toArray (nuovo Foo [0])' --- ** documentazione **: non c'è tempo per leggere ... –

+0

La semplicità è la chiave ... pensa che alcune persone si prenderanno a calci se stessi hehe – David

+5

@Carlos effettivamente, usa una memoria migliore di '(nuovo Foo [0])'. Come per la documentazione di Collection.toArray, '@param a la matrice in cui devono essere memorizzati gli elementi di questa raccolta, se è abbastanza grande', il che significa che li memorizzerà direttamente in quella nuova matrice. Se gli dai un array di dimensione 0, creerà un nuovo array, il che significa che hai un piccolo array e un grande array quando non è necessario. – corsiKa

10

Se lo si utilizza più di una volta o in un ciclo, si potrebbe definire una costante

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

e fare la conversione piace

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

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


Ecco la mia proposta per l'aggiornamento:

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[]{}); 
+1

ups, 'const' non è Java! 'public static final Foo [] FOO = {}' –

+1

perché dovrebbe essere pubblico? –

+0

@ Zoltán - perché no? È immutabile, quindi non presenta un problema di sicurezza. È un po 'ingombrante, ma potrebbe essere utile in altri codici, quindi è generalmente innocuo. Forse persino creare una classe centrale con tutte queste costanti e quindi usare 'import static' per ottenerle. – Jules

1

per l'originale vedere doublep risposta:

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<Foo> 
    bars[i++] = new Bar(foo); 
}  
3

Ecco la finale soluzione per il caso in aggiornamento sett ioni (con l'aiuto di Google Collezioni):

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

Ma, l'approccio chiave qui è stato menzionato in the doublep's answer (ho dimenticato per toArray metodo).

+1

Vedere il mio commento sulla risposta di doublep sulla sicurezza del thread, che si applica anche a questa soluzione. 'new Bar [0]' evita il problema. – Jules

26

soluzione alternativa al domanda aggiornato utilizzando Java 8:

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

Questo può essere ridotto a 'Bar [] result = foos.stream(). Map (Bar :: new) .toArray (Bar [] :: new);' – lpandzic

+0

Sintassi saggio Preferisco di gran lunga la risposta accettata . Vorrei che le persone possano passare a Python. –

Problemi correlati