Come convertire Set <String> in String []?


281

Devo String[]uscire da un Set<String>, ma non so come farlo. Non riesce:

Map<String, ?> myMap = gpxlist.getAll();
Set<String> myset = myMap.keySet();
String[] GPXFILES1 = (String[]) myset.toArray(); // Here it fails.

Come posso ripararlo in modo che funzioni?


5
Con il toArray()metodo che è chiaramente menzionato nel Javadoc.
Marchese di Lorne,


Java 11: Utilizzo nuovo toArray()metodo di default stackoverflow.com/a/32179686/1216775
akhil_mittal

Risposte:


461

Utilizzare il Set#toArray(T[])metodo prendendo un argomento array tipizzato della stessa dimensione.

String[] GPXFILES1 = myset.toArray(new String[myset.size()]);

È anche possibile utilizzare una dimensione diversa, ma ciò costringerebbe il toArray()metodo a creare un nuovo array da restituire invece di riutilizzare l'argomento fornito, il che potrebbe risultare meno efficiente.

Vedi anche il codice sorgente diAbstractCollection#toArray() .


5
Puoi anche specificare un array di dimensioni 0: String[] GPXFILES1 = myset.toArray(new String[0]);
sactiw,

1
@sactiw: è già coperto dall'altra risposta. Leggi il commento sull'altra risposta perché questo non è raccomandato.
BalusC,

8
Da Java 7 possiamo usare String[] GPXFILES1 = myset.toArray(new String[0])e questo è raccomandato. Aggiorna la risposta. "Dagli ultimi aggiornamenti di OpenJDK 6 questa chiamata è stata intrinseca, rendendo le prestazioni della versione dell'array vuota uguali e talvolta persino migliori, rispetto alla versione pre-dimensionata. Anche il passaggio dell'array pre-dimensionato è pericoloso per una raccolta simultanea o sincronizzata come è possibile una corsa di dati tra la dimensione e la chiamata toArray che può comportare ulteriori null alla fine dell'array, se la raccolta è stata contemporaneamente ridotta durante l'operazione. " - citato dalla comunità java.
Chaitanya,

6
Incontrando prima questa risposta e poi facendo ulteriori ricerche, ci sono alcune prove a supporto del fatto che il commento sopra sia corretto; e la risposta accettata non è aggiornata. Prendi questi link di esempio per quello che vuoi: stackoverflow.com/questions/9863742/… e un link da quel post SO shipilev.net/blog/2016/arrays-wisdom-ancients .
RMSD

60

Java 11

Il nuovo toArraymetodo predefinito Collectionnell'interfaccia consente di trasferire gli elementi della raccolta in un array appena creato del tipo di runtime desiderato. Si prende IntFunction<T[]> generatorcome argomento e può essere utilizzato come:

 String[] array = set.toArray(String[]::new);

Esiste già un metodo simile Collection.toArray(T[])e questa aggiunta significa che non saremo più in grado di passare nullcome argomento perché in tal caso il riferimento al metodo sarebbe ambiguo. Ma va ancora bene dato che entrambi i metodi lanciano comunque un NPE.

Java 8

In Java 8 possiamo usare le API degli stream:

String[] array = set.stream().toArray(String[]::new);

Possiamo anche utilizzare la versione sovraccarica di toArray () che assume IntFunction<A[]> generatorcome:

String[] array = set.stream().toArray(n -> new String[n]);

Lo scopo della funzione generatore qui è di prendere un numero intero (dimensione della matrice desiderata) e produrre una matrice della dimensione desiderata. Personalmente preferisco il primo approccio usando il metodo di riferimento rispetto al successivo usando l'espressione lambda.


non hai bisogno stream()di usare toArray(). Può essereset.toArray(new String[0])
Jakub Pomykała,

1
@ JakubPomykała In realtà non va bene. Quando si fornisce una matrice di dimensioni errate, internamente quella funzione deve utilizzare la riflessione per ottenere una dimensione corretta della matrice. Se è necessario questo metodo, basta farloset.toArray(new String[set.size()]);
Debosmit Ray,

42

Utilizzare il metodo toArray (T [] a) :

String[] array = set.toArray(new String[0]);

26
Quando si passa ad Array () un array di dimensioni troppo ridotte, il metodo toArray () deve costruire un nuovo array delle dimensioni giuste usando reflection. Ciò ha prestazioni significativamente peggiori rispetto al passaggio in un array di almeno le dimensioni della raccolta stessa. Pertanto [0]dovrebbe essere sostituito con [myset.size()]come nella risposta accettata.
k2col,

10
@ k2col sembra che ora set.toArray(new String[0])abbia una performance migliore diset.toArray(new String[set.size()]
Xam

1
Da Java 7 questo è l'approccio preferito. Vedere questo commento .
acdcjunior,



1
Set<String> stringSet= new HashSet<>();
String[] s = (String[])stringSet.toArray();

0

Stavo affrontando la stessa situazione.

Comincio dichiarando le strutture di cui ho bisogno:

Set<String> myKeysInSet = null; String[] myArrayOfString = null;

Nel mio caso, ho un oggetto JSON e ho bisogno che tutte le chiavi in ​​questo JSON siano archiviate in una matrice di stringhe. Usando la libreria GSON , uso JSON.keySet () per ottenere le chiavi e passare al mio set:

myKeysInSet = json_any.keySet();

Con questo, ho una struttura Set con tutte le chiavi, di cui avevo bisogno. Quindi ho solo bisogno dei valori del mio array di stringhe. Vedi il codice qui sotto:

myArrayOfString = myKeysInSet.toArray(new String[myKeysInSet.size()]);

Questa è stata la mia prima risposta in StackOverflow. Ci scusiamo per qualsiasi errore: D

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.