Expression Lambda pour convertir un tableau / une liste de chaînes en tableau / une liste d'entiers


111

Puisque Java 8 est livré avec de puissantes expressions lambda,

Je voudrais écrire une fonction pour convertir une liste / tableau de chaînes en tableau / liste d'entiers, flottants, doubles, etc.

En Java normal, ce serait aussi simple que

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

Mais comment obtenir la même chose avec un lambda, étant donné un tableau de chaînes à convertir en un tableau d'entiers.

Réponses:


128

Vous pouvez créer des méthodes d'assistance qui convertiraient une liste (tableau) de type Ten liste (tableau) de type en Uutilisant l' mapopération sur 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);
}

Et utilisez-le comme ceci:

//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);


Notez qui s -> Integer.parseInt(s)pourrait être remplacé par Integer::parseInt(voir les références de méthode )


5
Si vous utilisez Guava, vous pouvez également utiliser Lists.transform().
Alexandros du

Très bon exemple. La fonction rend le code plus polyvalent et plus puissant. Thks !!!
Marcelo Rebouças

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

5
Pouvez-vous expliquer cela un peu?
Unheilig

1
Il s'agit de convertir une liste de String en un flux, puis de mapper / convertir chaque élément de la liste en Integer, puis de collecter en une liste.
hemanto

5
Cela devrait être la réponse acceptée, car le point de lambdas (la question d'origine demande une expression lambda) est d'éviter de définir une nouvelle fonction. En plus de cela, cette réponse utilise élégamment la fonction existante Integer :: valueOf
Jonathan Benn

31

Les méthodes d'assistance de la réponse acceptée ne sont pas nécessaires. Les flux peuvent être utilisés avec des lambdas ou généralement raccourcis à l'aide de références de méthode . Les flux permettent des opérations fonctionnelles. map()convertit les éléments et / collect(...)ou toArray()encapsule le flux dans un tableau ou une collection.

Le discours (vidéo) de Venkat Subramaniam l' explique mieux que moi.

1 Convertir List<String>enList<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 Convertir List<String>enint[]

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

3 Convertir String[]enList<Integer>

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

4 Convertir String[]enint[]

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

5 Convertir String[]enList<Double>

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

6 (bonus) Convertir int[]enString[]

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

Bien sûr, beaucoup plus de variations sont possibles.

Voir également la version Ideone de ces exemples . Peut cliquer sur fork, puis exécuter pour exécuter dans le navigateur.


7

EDIT: Comme indiqué dans les commentaires, il s'agit d'une version beaucoup plus simple: De Arrays.stream(stringArray).mapToInt(Integer::parseInt).toArray() cette façon, nous pouvons ignorer toute la conversion vers et depuis une liste.


J'ai trouvé une autre solution en une ligne, mais elle est encore assez lente (prend environ 100 fois plus de temps qu'un cycle for - testé sur un tableau de 6000 0)

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

Ce que cela fait:

  1. Arrays.asList () convertit le tableau en List
  2. .stream le convertit en un Stream (nécessaire pour effectuer une carte)
  3. .map (Integer :: parseInt) convertit tous les éléments du flux en nombres entiers
  4. .mapToInt (i-> i) convertit tous les entiers en entiers (vous n'avez pas à faire cela si vous ne voulez que des entiers)
  5. .toArray () convertit le Stream en un tableau

13
Vous n'avez pas besoin des étapes 1 et 4:Arrays.stream(stringArray).mapToInt(Integer::parseInt).toArray()
xehpuk

3

Pour la liste:

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

Pour Array:

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

2

Vous pouvez aussi utiliser,

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

Je ne l'ai pas trouvé dans les réponses précédentes, donc, avec Java 8 et les flux:

Convertir String[]en Integer[]:

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

-1

De plus - contrôlez quand le tableau de chaînes n'a pas d'éléments:

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

-1

J'ai utilisé maptoInt () avec l'opération Lambda pour convertir une chaîne en entier

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

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.