Qual é a maneira mais fácil / mais curta de converter um Java 8 Stream
em uma matriz?
Qual é a maneira mais fácil / mais curta de converter um Java 8 Stream
em uma matriz?
Respostas:
O método mais fácil é usar o toArray(IntFunction<A[]> generator)
método com uma referência de construtor de matriz. Isso é sugerido na documentação da API do método .
String[] stringArray = stringStream.toArray(String[]::new);
O que ele faz é encontrar um método que aceita um número inteiro (o tamanho) como argumento e retorna a String[]
, que é exatamente o que (uma das sobrecargas de) new String[]
faz.
Você também pode escrever o seu IntFunction
:
Stream<String> stringStream = ...;
String[] stringArray = stringStream.toArray(size -> new String[size]);
O objetivo do IntFunction<A[]> generator
é converter um número inteiro, o tamanho da matriz, em uma nova matriz.
Código de exemplo:
Stream<String> stringStream = Stream.of("a", "b", "c");
String[] stringArray = stringStream.toArray(size -> new String[size]);
Arrays.stream(stringArray).forEach(System.out::println);
Impressões:
a
b
c
toArray(sz -> new String[sz])
isso, então não tenho certeza de que se possa realmente dizer qual deve ou deve ser a solução.
sz -> new String[sz]
uma nova função onde, como a referência do construtor, não. Depende de quanto você valoriza a Garbage Collection Churn, eu acho.
private
método novo, que não pode causar rotatividade, e as duas versões precisam criar um novo objeto. Uma referência cria um objeto que aponta diretamente para o método de destino; um lambda cria um objeto que aponta para o gerado private
. Uma referência a um construtor ainda deve ter um desempenho melhor por falta de indireção e otimização mais fácil da VM, mas a agitação não tem nada a ver com isso.
Se você deseja obter uma matriz de entradas, com valores de 1 a 10, de um Stream, há o IntStream à sua disposição.
Aqui, criamos um Stream com o método Stream.of e convertemos um Stream em um IntStream usando um mapToInt. Em seguida, podemos chamar o método toArray do 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();
Aqui está a mesma coisa, sem o Stream, usando apenas o IntStream
int[]array2 = IntStream.rangeClosed(1, 10).toArray();
Você pode converter um fluxo java 8 em uma matriz usando este bloco de código simples:
String[] myNewArray3 = myNewStream.toArray(String[]::new);
Mas vamos explicar mais, primeiro, vamos criar uma lista de strings preenchidas com três valores:
String[] stringList = {"Bachiri","Taoufiq","Abderrahman"};
Crie um fluxo a partir da matriz fornecida:
Stream<String> stringStream = Arrays.stream(stringList);
agora podemos executar algumas operações nesse fluxo Ex:
Stream<String> myNewStream = stringStream.map(s -> s.toUpperCase());
e, finalmente, converta-o em uma matriz java 8 usando estes métodos:
Método 1-Classic (interface funcional)
IntFunction<String[]> intFunction = new IntFunction<String[]>() {
@Override
public String[] apply(int value) {
return new String[value];
}
};
String[] myNewArray = myNewStream.toArray(intFunction);
Expressão 2 -ambda
String[] myNewArray2 = myNewStream.toArray(value -> new String[value]);
3- Referência do método
String[] myNewArray3 = myNewStream.toArray(String[]::new);
Referência de método Explicação:
É outra maneira de escrever uma expressão lambda que é estritamente equivalente à outra.
Converta o texto na matriz de cadeias onde separa cada valor por vírgula e apara todos os campos, por exemplo:
String[] stringArray = Arrays.stream(line.split(",")).map(String::trim).toArray(String[]::new);
Você pode criar um coletor personalizado que converte um fluxo em matriz.
public static <T> Collector<T, ?, T[]> toArray( IntFunction<T[]> converter )
{
return Collectors.collectingAndThen(
Collectors.toList(),
list ->list.toArray( converter.apply( list.size() ) ) );
}
e um uso rápido
List<String> input = Arrays.asList( ..... );
String[] result = input.stream().
.collect( CustomCollectors.**toArray**( String[]::new ) );
Collectors.groupingBy
para que eu pudesse mapear algum atributo para matrizes de objetos por valor de atributo. Essa resposta me dá exatamente isso. Também @DidierL.
Usar o toArray(IntFunction<A[]> generator)
método é realmente uma maneira muito elegante e segura de converter (ou mais corretamente, coletar) um fluxo em uma matriz do mesmo tipo do fluxo.
No entanto, se o tipo da matriz retornada não for importante, o simples uso do toArray()
método será mais fácil e mais curto. Por exemplo:
Stream<Object> args = Stream.of(BigDecimal.ONE, "Two", 3);
System.out.printf("%s, %s, %s!", args.toArray());
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);
}
}
}
Experimente online: https://repl.it/@SmaMa/Stream-to-array
Stream<Integer> stream = Stream.of(1, 2, 3, 4, 5, 6);
Integer[] integers = stream.toArray(it->new Integer[it]);
Você pode fazê-lo de várias maneiras. Todas as formas são tecnicamente iguais, mas o uso do Lambda simplificaria parte do código. Digamos que inicializamos uma Lista primeiro com String, chame-a de pessoas.
List<String> persons = new ArrayList<String>(){{add("a"); add("b"); add("c");}};
Stream<String> stream = persons.stream();
Agora você pode usar uma das seguintes maneiras.
Usando a expressão Lambda para criar um novo StringArray com tamanho definido.
String [] stringArray = stream.toArray (tamanho-> novo String [tamanho]);
Usando a referência do método diretamente.
String [] stringArray = stream.toArray (String [] :: new);