Expressão lambda para converter array / Lista de String em array / Lista de Inteiros


111

Como o Java 8 vem com expressões lambda poderosas,

Eu gostaria de escrever uma função para converter uma lista / array de strings em array / lista de inteiros, flutuantes, duplos etc.

Em Java normal, seria tão simples quanto

for(String str : strList){
   intList.add(Integer.valueOf(str));
}

Mas como faço para conseguir o mesmo com um lambda, considerando uma matriz de Strings a ser convertida em uma matriz de Inteiros.

Respostas:


128

Você poderia criar métodos auxiliares que converteriam uma lista (array) do tipo Tem uma lista (array) do tipo Uusando a mapoperação on stream.

//for lists
public static <T, U> List<U> convertList(List<T> from, Function<T, U> func) {
    return from.stream().map(func).collect(Collectors.toList());
}

//for arrays
public static <T, U> U[] convertArray(T[] from, 
                                      Function<T, U> func, 
                                      IntFunction<U[]> generator) {
    return Arrays.stream(from).map(func).toArray(generator);
}

E use-o assim:

//for lists
List<String> stringList = Arrays.asList("1","2","3");
List<Integer> integerList = convertList(stringList, s -> Integer.parseInt(s));

//for arrays
String[] stringArr = {"1","2","3"};
Double[] doubleArr = convertArray(stringArr, Double::parseDouble, Double[]::new);


Observe que s -> Integer.parseInt(s)pode ser substituído por Integer::parseInt(consulte as referências de método )


5
Se estiver usando Guava, você também pode usar Lists.transform().
Alexandros,

Muito bom exemplo. A função torna o código mais versátil e poderoso. Thks !!!
Marcelo Rebouças

127
List<Integer> intList = strList.stream()
                               .map(Integer::valueOf)
                               .collect(Collectors.toList());

5
Você pode explicar isso um pouco?
Unheilig de

1
Isso é converter uma lista de String em um fluxo, em seguida, mapear / converter cada elemento da lista em Inteiro e coletar em uma lista.
hemanto

5
Essa deve ser a resposta aceita, já que o objetivo dos lambdas (a questão original pede uma expressão lambda) é evitar a definição de uma nova função. Além disso, esta resposta usa elegantemente a função Integer :: valueOf existente
Jonathan Benn

31

Os métodos auxiliares da resposta aceita não são necessários. Os fluxos podem ser usados ​​com lambdas ou geralmente encurtados usando referências de método . Streams permitem operações funcionais. map()converte os elementos e / collect(...)ou toArray()envolve o fluxo de volta em uma matriz ou coleção.

A palestra (vídeo) de Venkat Subramaniam explica isso melhor do que eu.

1 converter List<String>paraList<Integer>

List<String> l1 = Arrays.asList("1", "2", "3");
List<Integer> r1 = l1.stream().map(Integer::parseInt).collect(Collectors.toList());

// the longer full lambda version:
List<Integer> r1 = l1.stream().map(s -> Integer.parseInt(s)).collect(Collectors.toList());

2 Converter List<String>paraint[]

int[] r2 = l1.stream().mapToInt(Integer::parseInt).toArray();

3 Converter String[]paraList<Integer>

String[] a1 = {"4", "5", "6"};
List<Integer> r3 = Stream.of(a1).map(Integer::parseInt).collect(Collectors.toList());

4 converter String[] paraint[]

int[] r4 = Stream.of(a1).mapToInt(Integer::parseInt).toArray();

5 converter String[] paraList<Double>

List<Double> r5 = Stream.of(a1).map(Double::parseDouble).collect(Collectors.toList());

6 (bônus) Converter int[] paraString[]

int[] a2 = {7, 8, 9};
String[] r6 = Arrays.stream(a2).mapToObj(Integer::toString).toArray(String[]::new);

Muitas outras variações são possíveis, é claro.

Veja também a versão Ideone desses exemplos . Pode clicar em fork e, em seguida, executar para executar no navegador.


7

EDIT: Como apontado nos comentários, esta é uma versão muito mais simples: Arrays.stream(stringArray).mapToInt(Integer::parseInt).toArray() Desta forma, podemos pular toda a conversão de e para uma lista.


Eu encontrei outra solução de uma linha, mas ainda é muito lenta (leva cerca de 100 vezes mais do que um ciclo for - testado em uma matriz de 6.000 zeros)

String[] stringArray = ...
int[] out= Arrays.asList(stringArray).stream().map(Integer::parseInt).mapToInt(i->i).toArray();

O que isso faz:

  1. Arrays.asList () converte a matriz em uma lista
  2. .stream o converte em um Stream (necessário para realizar um mapa)
  3. .map (Integer :: parseInt) converte todos os elementos no stream em inteiros
  4. .mapToInt (i-> i) converte todos os inteiros em ints (você não precisa fazer isso se quiser apenas inteiros)
  5. .toArray () converte o Stream de volta em uma matriz

13
Você não precisa das etapas 1 e 4:Arrays.stream(stringArray).mapToInt(Integer::parseInt).toArray()
xehpuk

3

Para a lista:

List<Integer> intList 
 = stringList.stream().map(Integer::valueOf).collect(Collectors.toList());

Para Array:

int[] intArray = Arrays.stream(stringArray).mapToInt(Integer::valueOf).toArray();

2

Você também pode usar,

List<String> list = new ArrayList<>();
    list.add("1");
    list.add("2");
    list.add("3");

    Integer[] array = list.stream()
        .map( v -> Integer.valueOf(v))
        .toArray(Integer[]::new);

0

Não o encontrei nas respostas anteriores, portanto, com Java 8 e streams:

Converter String[]para Integer[]:

Arrays.stream(stringArray).map(Integer::valueOf).toArray(Integer[]::new)

-1

Além disso - controle quando a matriz de string não tem elementos:

Arrays.stream(from).filter(t -> (t != null)&&!("".equals(t))).map(func).toArray(generator) 

-1

Usei maptoInt () com operação Lambda para converter string em inteiro

int[] arr = Arrays.stream(stringArray).mapToInt(item -> Integer.parseInt(item)).toArray();

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.