Dizi / Dizge Listesini diziye / Tamsayılar Listesi'ne dönüştürmek için Lambda ifadesi


111

Java 8 güçlü lambda ifadeleriyle birlikte geldiğinden,

Bir Dizeler Listesini / dizisini diziye / Tamsayılar Listesi, Kayanlar, Çiftler vb. Dönüştürmek için bir işlev yazmak istiyorum.

Normal Java'da, bu kadar basit olurdu

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

Ancak, bir Tamsayılar dizisine dönüştürülecek bir Dizeler dizisi verildiğinde, bir lambda ile aynı şeyi nasıl başarabilirim?

Yanıtlar:


128

Sen türünün bir listesini (dizi) dönüştürmek istiyorum yardımcı yöntemler oluşturabilir Ttip bir listesi (dizi) için Ukullanma mapüzerine operasyon 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);
}

Ve bunu şu şekilde kullanın:

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


Bununla s -> Integer.parseInt(s)değiştirilebileceğini unutmayın Integer::parseInt(bkz. Yöntem referansları )


5
Guava kullanıyorsanız, kullanabilirsiniz Lists.transform().
Alexandros

Çok güzel bir örnek. İşlev, kodu daha çok yönlü ve güçlü hale getirir. Thks !!!
Marcelo Rebouças

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

5
Bunu biraz açıklayabilir misin?
Unheilig

1
Bu, bir String listesini bir akışa dönüştürmek, ardından listenin her öğesini Tamsayıya eşlemek / dönüştürmek ve ardından bir liste halinde toplamaktır.
hemanto

5
Lambdas'ın amacı (orijinal soru bir lambda ifadesini sorar) yeni bir işlevi tanımlamaktan kaçınmak olduğundan, bu kabul edilen yanıt olmalıdır. Bunun da ötesinde, bu yanıt mevcut Tamsayı :: valueOf işlevini zarif bir şekilde kullanır
Jonathan Benn

31

Kabul edilen cevaptan yardımcı yöntemlere ihtiyaç yoktur. Akışlar lambdalarla kullanılabilir veya genellikle Yöntem Referansları kullanılarak kısaltılabilir . Akışlar, işlevsel işlemleri mümkün kılar. map()öğeleri dönüştürür ve collect(...)veya toArray()akışı bir dizi veya koleksiyona geri sarar.

Venkat Subramaniam'ın konuşması (video) bunu benden daha iyi açıklıyor.

1 dönüştürme List<String>iç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 dönüştürme List<String>içinint[]

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

3 dönüştürme String[]içinList<Integer>

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

4 dönüştürme String[]içinint[]

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

5 dönüştürme String[]içinList<Double>

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

6 (Bonus) dönüştürme int[]içinString[]

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

Elbette çok daha fazla varyasyon mümkündür.

Ayrıca bu örneklerin Ideone versiyonuna bakın . Çatalı tıklayabilir ve ardından tarayıcıda çalıştırmak için çalıştırabilir.


7

DÜZENLEME: Yorumlarda belirtildiği gibi, bu çok daha basit bir versiyondur: Arrays.stream(stringArray).mapToInt(Integer::parseInt).toArray() Bu şekilde, bir listeye ve listeden tüm dönüşümü atlayabiliriz.


Başka bir tek satırlık çözüm buldum, ancak yine de oldukça yavaş (döngü için yaklaşık 100 kat daha uzun sürüyor - 6000 0'lık bir dizide test edildi)

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

Bu ne yapar:

  1. Arrays.asList (), diziyi Listeye dönüştürür
  2. .stream bunu bir Akışa dönüştürür (bir harita gerçekleştirmek için gereklidir)
  3. .map (Tamsayı :: parseInt) akımdaki tüm öğeleri Tamsayılara dönüştürür
  4. .mapToInt (i-> i) tüm Tamsayıları tamsayılara dönüştürür (yalnızca Tamsayılar istiyorsanız bunu yapmanız gerekmez)
  5. .toArray (), Akışı tekrar bir diziye dönüştürür

13
1. ve 4. adımlara ihtiyacınız yok:Arrays.stream(stringArray).mapToInt(Integer::parseInt).toArray()
xehpuk

3

Liste için:

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

Dizi için:

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

2

Ayrıca kullanabilirsiniz,

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

Önceki cevaplarda bulamadım, bu yüzden Java 8 ve akışlarda:

Dönüştürme String[]için Integer[]:

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

-1

Ek olarak - dizge dizisinde eleman olmadığında kontrol edin:

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

-1

String'i Tamsayıya dönüştürmek için lambda işlemi ile maptoInt () kullandım

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

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.