Cómo convertir una secuencia de Java 8 a una matriz?


459

¿Cuál es la forma más fácil/más corta de convertir un Java 8 Stream en una matriz?

+2

le sugeriría a revertir la reversión como la cuestión era más completa y demostró que había intentado algo. 15 abr. 142014-04-15 09:13:21

  0

@skiwi Gracias! pero pensé que el intento de código realmente no agrega más información a la pregunta, y nadie ha gritado "muéstranos tu intento" todavía =) 15 abr. 142014-04-15 09:20:32

+12

@skiwi: Aunque suelo gritarle a los do-my-homework-instead-of-me preguntas, esta pregunta en particular parece ser más clara para mí sin ningún lío adicional. Vamos a mantenerlo ordenado. 16 abr. 142014-04-16 11:21:24

692

El método más fácil es utilizar el método toArray(IntFunction<A[]> generator) con una referencia de constructor de matriz. Esto se sugiere en el API documentation for the method.

String[] stringArray = streamString.toArray(String[]::new); 

Lo que hace, es encontrar un método que toma en un entero (el tamaño) como argumento y devuelve un String[], que es exactamente lo que (una de las sobrecargas de) new String[] hace.

También puede escribir su propia IntFunction:

Stream<String> stream = ...; 
String[] stringArray = stream.toArray(size -> new String[size]); 

El propósito de la IntFunction<A[]> generator es convertir un entero, el tamaño de la matriz, a una nueva matriz.

código Ejemplo:

Stream<String> streamString = Stream.of("a", "b", "c"); 
String[] stringArray = streamString.toArray(size -> new String[size]); 
Arrays.stream(stringArray).forEach(System.out::println); 

Lienzo:

a 
b 
c 
+176

'String [] :: new' es un buen truco; más directo que una expresión lambda, en mi opinión. 18 dic. 142014-12-18 07:55:54

+11

Zenexer tiene razón, la solución debería ser: 'stream.toArray (String [] :: new);' 01 oct. 152015-10-01 13:01:08

+4

y aquí hay una explicación de por qué y cómo funciona realmente la referencia del constructor Array: http://stackoverflow.com/ preguntas/29447561/how-do-java-8-array-constructor-references-work 12 sep. 162016-09-12 18:16:38

  0

* "Zenexer tiene razón, la solución debería ser: stream.toArray (String [] :: new);" * ... Bien, bien , pero uno debe entender que la referencia del método es lógicamente y funcionalmente equivalente a 'toArray (sz -> new String [sz])' así que no estoy seguro de que uno realmente pueda decir lo que la solución debe o debe ser. 20 abr. 172017-04-20 14:16:02

  0

La referencia del constructor de matriz es más conciso. La documentación para el método 'toArray()' cita su concisión e incluye su uso en el único ejemplo. Cuando se insertó al final de la respuesta, me lo perdí en la primera lectura. Se movió a la parte superior, por encima de los detalles, para que nadie más lo pierda. 01 may. 172017-05-01 19:44:05

+2

@scottb 'sz -> new String [sz]' hace una nueva función donde no lo hace la referencia del constructor. Depende de cuánto valoras Garbage Collection Churn. 18 ago. 172017-08-18 09:19:42

+1

@WORMSS No es así. (¡Estáticamente!) Crea un nuevo método 'privado' *, que no puede causar abandono, y * ambas * versiones necesitan crear un nuevo objeto. Una referencia crea un objeto que apunta directamente al método objetivo; un lambda crea un objeto que apunta al 'privado' generado. Una referencia a un constructor debería funcionar aún mejor por falta de direccionamiento indirecto y una optimización más sencilla de VM, pero el batido no tiene nada que ver con eso. 29 oct. 172017-10-29 23:54:01

  0

@HTNW tienes razón, me disculpo. De hecho, fue mi intento de depurar lo que estaba causando la rotación que estaba causando la rotación la primera vez que traté de hacer esto, así que me quedé atrapado en mi cabeza de que así era. (Odio cuando eso sucede). 30 oct. 172017-10-30 08:38:59


17

Si desea obtener una matriz de enteros, con valores de la forma 1 a 10, de una corriente, hay IntStream a su disposición .

Aquí creamos un Stream con un método Stream.of y convertimos un Stream en un IntStream usando un mapToInt. Entonces podemos llamar al método toArray de IntStream.

Stream<Integer> stream = Stream.of(1,2,3,4,5,6,7,8,9,10); 
//or use this to create our stream 
//Stream<Integer> stream = IntStream.rangeClosed(1, 10).boxed(); 
int[] array = stream.mapToInt(x -> x).toArray(); 

Aquí es lo mismo, sin la corriente, utilizando sólo el IntStream

int[]array2 = IntStream.rangeClosed(1, 10).toArray(); 

2

Se puede crear un colector a medida que se convierten en una corriente de matriz.

public static <T> Collector<T, ?, T[]> toArray(IntFunction<T[]> converter) 
{ 
    return Collectors.collectingAndThen( 
        Collectors.toList(), 
        list ->list.toArray(converter.apply(list.size()))); 
} 

y un uso rápido

List<String> input = Arrays.asList(.....); 

String[] result = input.stream(). 
     .collect(CustomCollectors.**toArray**(String[]::new)); 

0
 Stream<Integer> stream = Stream.of(1, 2, 3, 4, 5, 6); 

    Integer[] integers = stream.toArray(it->new Integer[it]); 

0

Puede convertir una corriente de Java 8 a una matriz mediante este sencillo bloque de código:

String[] myNewArray3 = myNewStream.toArray(String[]::new); 

Pero vamos a explicar más cosas, primero, creemos una lista de cadenas llenas con tres valores:

String[] stringList = {"Bachiri","Taoufiq","Abderrahman"}; 

Crear una corriente de la matriz dada:

Stream<String> stringStream = Arrays.stream(stringList); 

ahora podemos realizar algunas operaciones en esta corriente Ex:

Stream<String> myNewStream = stringStream.map(s -> s.toUpperCase()); 

y finalmente convertirla en una matriz de Java 8 utilizando estos métodos :

1-Classic método (interfaz funcional)

IntFunction<String[]> intFunction = new IntFunction<String[]>() { 
    @Override 
    public String[] apply(int value) { 
     return new String[value]; 
    } 
}; 


String[] myNewArray = myNewStream.toArray(intFunction); 

2 expresión -Lambda

String[] myNewArray2 = myNewStream.toArray(value -> new String[value]); 

3- Método de referencia

String[] myNewArray3 = myNewStream.toArray(String[]::new); 

método de referencia Explicación:

Es otra manera de escribir una expresión lambda que es estrictamente equivalente a la otra.


2

El uso del método toArray(IntFunction<A[]> generator) es de hecho una forma muy elegante y segura de convertir (o más correctamente, recopilar) una transmisión en una matriz del mismo tipo de la secuencia.

Sin embargo, si el tipo del conjunto devuelto no es importante, simplemente usar el método toArray() es más fácil y más corto. Por ejemplo:

Stream<Object> args = Stream.of(BigDecimal.ONE, "Two", 3); 
    System.out.printf("%s, %s, %s!", args.toArray());