Espressione lambda per convertire array / elenco di stringhe in array / elenco di numeri interi


111

Poiché Java 8 è dotato di potenti espressioni lambda,

Vorrei scrivere una funzione per convertire un elenco / array di stringhe in array / elenco di numeri interi, float, doppi ecc.

In Java normale, sarebbe semplice come

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

Ma come posso ottenere lo stesso risultato con un lambda, dato un array di stringhe da convertire in un array di numeri interi.

Risposte:


128

È possibile creare metodi di supporto che convertano un elenco (array) di tipo Tin un elenco (array) di tipo Uutilizzando l' mapoperazione su 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 usalo in questo modo:

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


Nota che s -> Integer.parseInt(s)potrebbe essere sostituito con Integer::parseInt(vedi Riferimenti ai metodi )


5
Se stai usando Guava, puoi anche usare Lists.transform().
Alexandros

Ottimo esempio. La funzione rende il codice più versatile e potente. Thks !!!
Marcelo Rebouças

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

5
Puoi spiegarlo un po '?
Unheilig

1
Si tratta di convertire un elenco di String in uno stream, quindi mappare / convertire ogni elemento dell'elenco in Integer e quindi raccogliere in un elenco.
Hemanto

5
Questa dovrebbe essere la risposta accettata, poiché lo scopo di lambda (la domanda originale richiede un'espressione lambda) è evitare di definire una nuova funzione. Inoltre, questa risposta utilizza elegantemente la funzione Integer :: valueOf esistente
Jonathan Benn

31

I metodi di supporto dalla risposta accettata non sono necessari. I flussi possono essere usati con lambda o in genere abbreviati utilizzando riferimenti ai metodi . I flussi consentono operazioni funzionali. map()converte gli elementi collect(...)eo toArray()avvolge il flusso di nuovo in un array o in una raccolta.

Il discorso di Venkat Subramaniam (video) lo spiega meglio di me.

1 Converti List<String>inList<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 Converti List<String>inint[]

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

3 Converti String[]inList<Integer>

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

4 Converti String[]inint[]

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

5 Converti String[]inList<Double>

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

6 (bonus) Converti int[]inString[]

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

Ovviamente sono possibili molte più variazioni.

Vedi anche la versione Ideone di questi esempi . Può fare clic su fork e quindi eseguire per eseguire nel browser.


7

EDIT: come sottolineato nei commenti, questa è una versione molto più semplice: in Arrays.stream(stringArray).mapToInt(Integer::parseInt).toArray() questo modo possiamo saltare l'intera conversione da e verso un elenco.


Ho trovato un'altra soluzione di una riga, ma è ancora piuttosto lenta (impiega circa 100 volte più a lungo di un ciclo for - testato su un array di 6000 0)

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

Cosa fa:

  1. Arrays.asList () converte l'array in un List
  2. .stream lo converte in un flusso (necessario per eseguire una mappa)
  3. .map (Integer :: parseInt) converte tutti gli elementi nel flusso in numeri interi
  4. .mapToInt (i-> i) converte tutti gli interi in interi (non devi farlo se vuoi solo gli interi)
  5. .toArray () converte il flusso di nuovo in un array

13
Non sono necessari i passaggi 1 e 4:Arrays.stream(stringArray).mapToInt(Integer::parseInt).toArray()
xehpuk

3

Per l'elenco:

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

Per array:

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

2

Puoi anche usare,

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

Non l'ho trovato nelle risposte precedenti, quindi, con Java 8 e stream:

Converti String[]in Integer[]:

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

-1

Inoltre, controlla quando l'array di stringhe non ha elementi:

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

-1

Ho usato maptoInt () con l'operazione Lambda per convertire la stringa in Integer

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

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.