Comment convertir Set <String> en String []?

281

Je dois obtenir un String[]d'un Set<String>, mais je ne sais pas comment le faire. Les échecs suivants:

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

Comment puis-je le réparer pour qu'il fonctionne?

suter
la source
5
Avec la toArray()méthode qui est clairement mentionnée dans le Javadoc.
Marquis de Lorne
1
Solution Java 8: stackoverflow.com/questions/5982447/…
akhil_mittal
Java 11: Utilisation de la nouvelle toArray()méthode par défaut stackoverflow.com/a/32179686/1216775
akhil_mittal

Réponses:

461

Utilisez la Set#toArray(T[])méthode en prenant un argument de tableau typé de la même taille.

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

Une taille différente peut également être utilisée, mais cela forcerait la toArray()méthode à créer un nouveau tableau à retourner au lieu de réutiliser l'argument fourni, ce qui pourrait s'avérer moins efficace.

Voir aussi le code source deAbstractCollection#toArray() .

BalusC
la source
5
Vous pouvez également spécifier un tableau de taille 0: String[] GPXFILES1 = myset.toArray(new String[0]);
sactiw
1
@sactiw: C'est déjà couvert par l'autre réponse. Lisez le commentaire sur l'autre réponse pourquoi ce n'est pas recommandé.
BalusC
8
Depuis Java 7, nous pouvons utiliser String[] GPXFILES1 = myset.toArray(new String[0])et c'est recommandé. Mettez à jour la réponse. "Depuis les dernières mises à jour d'OpenJDK 6, cet appel a été intrinsèque, ce qui rend les performances de la version de baie vide identiques et parfois même meilleures, par rapport à la version prédéfinie. une course aux données est possible entre la taille et l'appel toArray, ce qui peut entraîner des valeurs Null supplémentaires à la fin du tableau, si la collection a été réduite simultanément pendant l'opération. " - cité par la communauté java.
Chaitanya
6
En rencontrant cette réponse d'abord et en faisant plus de recherche, il y a des preuves pour soutenir que le commentaire ci-dessus est correct; et la réponse acceptée est obsolète. Prenez ces exemples de liens pour ce que vous voulez: stackoverflow.com/questions/9863742/… , et un lien de ce message SO shipilev.net/blog/2016/arrays-wisdom-ancients .
RMSD
60

Java 11

La nouvelle toArrayméthode par défaut dans l' Collectioninterface permet de transférer les éléments de la collection vers un tableau nouvellement créé du type d'exécution souhaité. Il prend IntFunction<T[]> generatorcomme argument et peut être utilisé comme:

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

Il existe déjà une méthode similaire Collection.toArray(T[])et cet ajout signifie que nous ne pouvons plus passer nulld'argument car dans ce cas, la référence à la méthode serait ambiguë. Mais tout va bien puisque les deux méthodes lancent quand même un NPE.

Java 8

En Java 8, nous pouvons utiliser l'API streams:

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

Nous pouvons également utiliser la version surchargée de toArray () qui prend IntFunction<A[]> generatorcomme:

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

Le but de la fonction de générateur ici est de prendre un entier (taille du tableau souhaité) et de produire un tableau de la taille souhaitée. Personnellement, je préfère l'ancienne approche utilisant la référence de méthode que la dernière utilisant l'expression lambda.

akhil_mittal
la source
vous n'avez pas besoin stream()d'utiliser toArray(). Ça peut êtreset.toArray(new String[0])
Jakub Pomykała
1
@ JakubPomykała Ce n'est pas vraiment bon. Lorsque vous donnez un tableau de mauvaise taille, en interne, cette fonction doit utiliser la réflexion pour obtenir un tableau de taille correcte. Si cette méthode est nécessaire, faites-leset.toArray(new String[set.size()]);
Debosmit Ray
42

Utilisez la méthode toArray (T [] a) :

String[] array = set.toArray(new String[0]);
JMelnik
la source
26
Lorsque vous passez à toArray () un tableau de taille trop petite, la méthode toArray () doit construire un nouveau tableau de la bonne taille en utilisant la réflexion. Cela a des performances bien pires que de passer dans un tableau d'au moins la taille de la collection elle-même. Par conséquent, [0]devrait être remplacé par [myset.size()]comme dans la réponse acceptée.
k2col
10
@ k2col il semble que maintenant set.toArray(new String[0])a une meilleure performance queset.toArray(new String[set.size()]
Xam
1
Depuis Java 7, c'est l'approche préférée. Voir ce commentaire .
acdcjunior
1
Set<String> stringSet= new HashSet<>();
String[] s = (String[])stringSet.toArray();

la source
0

J'étais confronté à la même situation.

Je commence par déclarer les structures dont j'ai besoin:

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

Dans mon cas, j'ai un objet JSON et j'ai besoin que toutes les clés de ce JSON soient stockées dans un tableau de chaînes. En utilisant la bibliothèque GSON , j'utilise JSON.keySet () pour obtenir les clés et passer à mon Set:

myKeysInSet = json_any.keySet();

Avec cela, j'ai une structure Set avec toutes les clés, comme j'en avais besoin. J'ai donc juste besoin des valeurs de mon tableau de cordes. Voir le code ci-dessous:

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

C'était ma première réponse dans StackOverflow. Désolé pour toute erreur: D

João Vitor Veronese Vieira
la source