¿La forma más fácil de transformar la colección en matriz?

Supongamos que tenemos una Collection . ¿Cuál es la mejor forma (la más corta en LoC en el contexto actual) de transformarlo en Foo[] ? Se permiten todas las bibliotecas conocidas .

UPD: (un caso más en esta sección, deje comentarios si cree que vale la pena crear otro hilo para ello): ¿Qué pasa con la transformación de Collection a Bar[] donde Bar tiene constructor con 1 parámetro de tipo Foo ie public Bar(Foo foo){ ... } ?

Donde x es la colección:

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

Solución alternativa a la pregunta actualizada usando Java 8:

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

Si lo usa más de una vez o en un bucle, podría definir una constante

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

y hacer la conversión como

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

El método toArray tomará la matriz vacía para determinar el tipo correcto de la matriz objective y crear una nueva matriz para usted.


Aquí está mi propuesta para la actualización:

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

Aquí está la solución final para el caso en la sección de actualización (con la ayuda de Google Collections):

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

Pero, el enfoque clave aquí se mencionó en la respuesta del doublep (se me olvidó el método toArray ).

Para el original, vea la respuesta del doblete :

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

En cuanto a la actualización:

 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, una forma alternativa de convertir un Collection a un Foo[] podría ser hacer uso de Collection.toArray(IntFunction generator) como:

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

Como explica @Stuart en la lista de correo (énfasis mío), el rendimiento de esto debería ser esencialmente el mismo que el del Collection.toArray(new T[0]) existente Collection.toArray(new T[0])

El resultado es que las implementaciones que usan Arrays.copyOf( ) son las más rápidas, probablemente porque son intrínsecas .

Puede evitar llenar cero la matriz recién asignada porque sabe que se sobrescribirán los contenidos completos de la matriz. Esto es cierto independientemente de cómo se vea la API pública.

La implementación de la API dentro del JDK dice:

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

La implementación predeterminada llama a generator.apply(0) para obtener una matriz de longitud cero y luego simplemente llama a toArray(T[]) . Esto pasa por el camino rápido Arrays.copyOf() , por lo que es esencialmente la misma velocidad que en toArray(new T[0]) .


Nota : – Solo que el uso de la API debe guiarse junto con una incompatibilidad hacia atrás cuando se usa para código con valores null , por ejemplo, para toArray(null) ya que estas llamadas ahora serían ambiguas debido a existir en toArray(T[] a) y no comstackrían .