¿Cómo convertir Set <String> a String []?

281

Necesito String[]salir de un Set<String>, pero no sé cómo hacerlo. Lo siguiente falla:

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

¿Cómo puedo arreglarlo para que funcione?

suter
fuente
55
Con el toArray()método que se menciona claramente en el Javadoc.
Marqués de Lorne
1
Solución Java 8: stackoverflow.com/questions/5982447/…
akhil_mittal
Java 11: Uso del nuevo toArray()método predeterminado stackoverflow.com/a/32179686/1216775
akhil_mittal

Respuestas:

461

Utilice el Set#toArray(T[])método tomando un argumento de matriz con tipo del mismo tamaño.

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

También se puede usar un tamaño diferente, pero eso obligaría al toArray()método a crear una nueva matriz para que regrese en lugar de reutilizar el argumento proporcionado, que puede terminar siendo menos eficiente.

Ver también el código fuente deAbstractCollection#toArray() .

BalusC
fuente
55
También puede especificar una matriz de tamaño 0: String[] GPXFILES1 = myset.toArray(new String[0]);
sactiw
1
@sactiw: Eso ya está cubierto por la otra respuesta. Lea el comentario en la otra respuesta por qué esto no se recomienda.
BalusC
8
Desde Java 7 podemos usar String[] GPXFILES1 = myset.toArray(new String[0])y eso es recomendable. Actualiza la respuesta. "Desde las últimas actualizaciones de OpenJDK 6, esta llamada se intrinsificó, haciendo que el rendimiento de la versión de matriz vacía sea el mismo y, a veces, incluso mejor, en comparación con la versión de tamaño predeterminado. También es peligroso para una colección simultánea o sincronizada pasar una matriz de tamaño predeterminado. es posible una carrera de datos entre el tamaño y la llamada a la matriz que puede dar como resultado nulos adicionales al final de la matriz, si la colección se redujo simultáneamente durante la operación ". - Citado por la comunidad de Java.
Chaitanya
66
Al encontrar esta respuesta primero y luego investigar más, hay algunas pruebas que respaldan que el comentario anterior es correcto; y la respuesta aceptada no está actualizada. Tome estos enlaces de ejemplo para lo que quiera: stackoverflow.com/questions/9863742/… , y un enlace de esa publicación SO shipilev.net/blog/2016/arrays-wisdom-ancients .
RMSD
60

Java 11

El nuevo toArraymétodo predeterminado en la Collectioninterfaz permite que los elementos de la colección se transfieran a una matriz recién creada del tipo de tiempo de ejecución deseado. Se toma IntFunction<T[]> generatorcomo argumento y se puede utilizar como:

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

Ya existe un método similar Collection.toArray(T[])y esta adición significa que ya no podremos pasarlo nullcomo argumento porque en ese caso la referencia al método sería ambigua. Pero todavía está bien ya que ambos métodos arrojan un NPE de todos modos.

Java 8

En Java 8 podemos usar secuencias API:

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

También podemos hacer uso de la versión sobrecargada de toArray () que toma IntFunction<A[]> generatorcomo:

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

El propósito de la función del generador aquí es tomar un número entero (tamaño de la matriz deseada) y producir una matriz del tamaño deseado. Personalmente, prefiero el primer enfoque con referencia de método que el último con expresión lambda.

akhil_mittal
fuente
No necesitas stream()usar toArray(). Puede serset.toArray(new String[0])
Jakub Pomykała
1
@ JakubPomykała Eso en realidad no es bueno. Cuando da una matriz de tamaño incorrecto, internamente esa función tiene que usar la reflexión para obtener una matriz de tamaño correcto. Si se necesita este método, simplemente hazloset.toArray(new String[set.size()]);
Debosmit Ray
42

Utilice el método toArray (T [] a) :

String[] array = set.toArray(new String[0]);
JMelnik
fuente
26
Cuando pasa a Array () una matriz de tamaño demasiado pequeño, el método toArray () tiene que construir una nueva matriz del tamaño correcto utilizando la reflexión. Esto tiene un rendimiento significativamente peor que pasar una matriz de al menos el tamaño de la colección en sí. Por [0]lo tanto, debe reemplazarse [myset.size()]como en la respuesta aceptada.
k2col
10
@ k2col parece que ahora set.toArray(new String[0])tiene un mejor rendimiento queset.toArray(new String[set.size()]
Xam
1
Desde Java 7 este es el enfoque preferido. Ver este comentario .
acdcjunior
1
Set<String> stringSet= new HashSet<>();
String[] s = (String[])stringSet.toArray();

fuente
0

Estaba enfrentando la misma situación.

Comienzo declarando las estructuras que necesito:

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

En mi caso, tengo un objeto JSON y necesito que todas las claves en este JSON se almacenen en una matriz de cadenas. Usando la biblioteca GSON , uso JSON.keySet () para obtener las claves y moverme a mi Set:

myKeysInSet = json_any.keySet();

Con esto, tengo una estructura Set con todas las claves, ya que la necesitaba. Entonces solo necesito los valores para mi Array of Strings. Vea el código a continuación:

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

Esta fue mi primera respuesta en StackOverflow. Perdón por cualquier error: D

João Vitor Veronese Vieira
fuente