¿Cómo convertir una secuencia Java 8 en una matriz?


776

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


2
Le sugiero que revierta la reversión ya que la pregunta fue más completa y mostró que había intentado algo.
skiwi

2
@skiwi ¡Gracias! pero pensé que el intento de código realmente no agrega más información a la pregunta, y nadie ha gritado "

17
@skiwi: Aunque generalmente grito a las preguntas de hacer mi tarea en lugar de mí, esta pregunta en particular parece ser más clara para mí sin ningún problema adicional. Mantenlo ordenado.
Honza Zidek

Puede encontrar muchas respuestas y orientación en los documentos oficiales del paquete: docs.oracle.com/javase/8/docs/api/java/util/stream/…
Christophe Roussy

Respuestas:


1168

El método más fácil es usar el toArray(IntFunction<A[]> generator)método con una referencia de constructor de matriz. Esto se sugiere en la documentación de la API para el método .

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

Lo que hace es encontrar un método que tome un número entero (el tamaño) como argumento y devuelva a String[], que es exactamente lo que hace (una de las sobrecargas de) new String[].

También puedes escribir el tuyo IntFunction:

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

El propósito de la IntFunction<A[]> generatores convertir un número entero, el tamaño de la matriz, en una nueva matriz.

Código de ejemplo:

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

Huellas dactilares:

a
b
c

8
y aquí hay una explicación de por qué y cómo funciona realmente la referencia del constructor de Array: stackoverflow.com/questions/29447561/…
jarek.jpa

"Zenexer tiene razón, la solución debería ser: stream.toArray (String [] :: new);" ... Bueno, está bien, pero uno debe entender que la referencia del método es lógica y funcionalmente equivalente, por toArray(sz -> new String[sz])lo que no estoy seguro de que realmente se pueda decir cuál debería ser o debe ser la solución.
scottb

3
@scottb crea sz -> new String[sz]una nueva función donde la referencia del constructor no. Depende de cuánto valoras Garurn Collection Churn, supongo.
WORMSS

3
@WORMSS No lo hace. (¡Estáticamente!) Crea un nuevo private método , que no puede causar abandono, y ambas versiones necesitan crear un nuevo objeto. Una referencia crea un objeto que apunta directamente al método de destino; una lambda crea un objeto que apunta al generado private. Una referencia a un constructor aún debería funcionar mejor por falta de indirección y una optimización de VM más fácil, pero el batido no tiene nada que ver con eso.
HTNW

2
@HTNW tienes razón, te pido disculpas. De hecho, fue mi intento de depurar lo que estaba causando el abandono que estaba causando el abandono la primera vez que intenté hacer esto, así que he tenido en mi cabeza que así es como fue. (Odio cuando eso sucede).
WORMSS

41

Si desea obtener una matriz de entradas, con valores del 1 al 10, de un Stream, 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 Stream, usando solo IntStream

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

16

Puede convertir un flujo de Java 8 en una matriz usando este bloque de código simple:

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

Pero expliquemos más las cosas, primero, creemos una lista de cadenas llenas de tres valores:

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

Crear una secuencia de la matriz dada:

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

ahora podemos realizar algunas operaciones en esta secuencia Ej:

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

y finalmente conviértalo a java 8 Array usando estos métodos:

1-Método clásico (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 de Lambda

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

3- Referencia del método

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

Referencia del método Explicación:

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


7

Convierta el texto en una matriz de cadenas donde separe cada valor por coma y recorte cada campo, por ejemplo:

String[] stringArray = Arrays.stream(line.split(",")).map(String::trim).toArray(String[]::new);

5

Puede crear un recopilador personalizado que convierta una secuencia en 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 ) );

55
¿Por qué usarías esto en lugar de Stream.toArray (IntFunction) ?
Didier L

Necesitaba un colector para pasar al 2-arg Collectors.groupingBypara poder asignar algún atributo a matrices de objetos por valor de atributo. Esta respuesta me da exactamente eso. También @DidierL.
Ole VV

3

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

Sin embargo, si el tipo de matriz devuelta no es importante, simplemente usar el toArray()método 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());

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

int[] arr=   stream.mapToInt(x->x.intValue()).toArray();

0
import java.util.List;
import java.util.stream.Stream;

class Main {

    public static void main(String[] args) {
        // Create a stream of strings from list of strings
        Stream<String> myStreamOfStrings = List.of("lala", "foo", "bar").stream();

        // Convert stream to array by using toArray method
        String[] myArrayOfStrings = myStreamOfStrings.toArray(String[]::new);

        // Print results
        for (String string : myArrayOfStrings) {
            System.out.println(string);
        }
    }
}

Pruébelo en línea: https://repl.it/@SmaMa/Stream-to-array


¿Cuál es la diferencia entre su respuesta y la respuesta aceptada?
Long Nguyen

@LongNguyen Es un ejemplo completo que incluye un escenario de repetición en línea, no solo un fragmento.
Sma Ma

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

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

-2

Puede hacerlo de varias maneras. Todas las formas son técnicamente iguales, pero el uso de Lambda simplificaría parte del código. Digamos que inicializamos una Lista primero con String, llamémosla personas.

List<String> persons = new ArrayList<String>(){{add("a"); add("b"); add("c");}};
Stream<String> stream = persons.stream();

Ahora puede usar cualquiera de las siguientes formas.

  1. Usando la expresión Lambda para crear un nuevo StringArray con un tamaño definido.

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

  2. Usando el método de referencia directamente.

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

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.