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.

Reddy
la source

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 )

Alexis C.
la source
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());
ZehnVon12
la source
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.

Stan Kurdziel
la source
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
Passoire
la source
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();
Sahil Chhabra
la source
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);
Thangavel Loganathan
la source
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)
LeoLozes
la source
-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) 
Zhurov Konstantin
la source
-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();
Lotie profonde
la source
-3

Arrays.toString (int []) fonctionne pour moi.

Praveen Codur
la source
Je ne réponds pas à la question: "Comment y parvenir avec des lambdas".
Sergei Sirik