Ekspresi lambda untuk mengubah larik / Daftar String menjadi larik / Daftar Integer

111

Karena Java 8 hadir dengan ekspresi lambda yang kuat,

Saya ingin menulis sebuah fungsi untuk mengonversi Daftar / larik String menjadi larik / Daftar Integer, Floats, Ganda, dll.

Di Java normal, ini akan sesederhana

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

Tetapi bagaimana saya mencapai hal yang sama dengan lambda, diberi array String untuk diubah menjadi array Integer.

Reddy
sumber

Jawaban:

128

Anda bisa membuat metode pembantu yang akan mengubah daftar (larik) tipe Tmenjadi daftar (larik) jenis Umenggunakan mapoperasi pada 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);
}

Dan gunakan seperti ini:

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


Catatan yang s -> Integer.parseInt(s)bisa diganti dengan Integer::parseInt(lihat Referensi metode )

Alexis C.
sumber
5
Jika Anda menggunakan Jambu biji, Anda juga bisa menggunakan Lists.transform().
Alexandros
Contoh yang sangat bagus. Fungsi ini mengubah kode menjadi lebih fleksibel dan kuat. Terima kasih !!!
Marcelo Rebouças
127
List<Integer> intList = strList.stream()
                               .map(Integer::valueOf)
                               .collect(Collectors.toList());
ZehnVon12
sumber
5
Bisakah Anda menjelaskannya sedikit?
Unheilig
1
Ini mengubah daftar String menjadi aliran lalu memetakan / mengubah setiap elemen daftar menjadi Integer lalu mengumpulkannya menjadi daftar.
hemanto
5
Ini harus menjadi jawaban yang diterima, karena inti dari lambda (pertanyaan asli meminta ekspresi lambda) adalah untuk menghindari pendefinisian fungsi baru. Selain itu, jawaban ini dengan elegan menggunakan fungsi Integer :: valueOf yang ada
Jonathan Benn
31

Metode helper dari jawaban yang diterima tidak diperlukan. Aliran dapat digunakan dengan lambda atau biasanya disingkat menggunakan Referensi Metode . Aliran memungkinkan operasi fungsional. map()mengonversi elemen dan collect(...)atau toArray()membungkus aliran kembali menjadi larik atau koleksi.

Pembicaraan (video) Venkat Subramaniam menjelaskannya lebih baik dari saya.

1 Konversi List<String>keList<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 Ubah List<String>menjadiint[]

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

3 Konversi String[] menjadiList<Integer>

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

4 Konversi String[] menjadiint[]

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

5 Konversi String[] menjadiList<Double>

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

6 (bonus) Konversi int[] keString[]

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

Lebih banyak variasi yang dimungkinkan tentunya.

Lihat juga versi Ideone dari contoh ini . Bisa klik garpu lalu jalankan untuk dijalankan di browser.

Stan Kurdziel
sumber
7

EDIT: Seperti yang ditunjukkan di komentar, ini adalah versi yang jauh lebih sederhana: Arrays.stream(stringArray).mapToInt(Integer::parseInt).toArray() Dengan cara ini kita dapat melewati seluruh konversi ke dan dari daftar.


Saya menemukan solusi satu baris lain, tetapi masih cukup lambat (memakan waktu sekitar 100 kali lebih lama dari siklus untuk - diuji pada array 6000 0)

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

Apa fungsinya:

  1. Arrays.asList () mengonversi larik menjadi Daftar
  2. .stream mengubahnya menjadi Stream (diperlukan untuk melakukan peta)
  3. .map (Integer :: parseInt) mengonversi semua elemen dalam aliran menjadi Integers
  4. .mapToInt (i-> i) mengonversi semua Integer menjadi int (Anda tidak perlu melakukan ini jika Anda hanya menginginkan Integer)
  5. .toArray () mengonversi Stream kembali ke array
Saringan
sumber
13
Anda tidak memerlukan langkah 1 dan 4:Arrays.stream(stringArray).mapToInt(Integer::parseInt).toArray()
xehpuk
3

Untuk Daftar:

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

Untuk Array:

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

Anda juga bisa menggunakan,

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);
pengguna2182920
sumber
0

Saya tidak menemukannya di jawaban sebelumnya, jadi, dengan Java 8 dan aliran:

Ubah String[]menjadi Integer[]:

Arrays.stream(stringArray).map(Integer::valueOf).toArray(Integer[]::new)
LeoLozes
sumber
-1

Selain itu - kontrol ketika array string tidak memiliki elemen:

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

Saya menggunakan maptoInt () dengan operasi Lambda untuk mengubah string menjadi Integer

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

Arrays.toString (int []) bekerja untuk saya.

Praveen Codur
sumber
Saya tidak menjawab pertanyaan: "Bagaimana mencapai ini dengan lambda".
Sergei Sirik