Kode ini berfungsi (diambil di Javadoc):
List<Integer> numbers = Arrays.asList(1, 2, 3, 4);
String commaSeparatedNumbers = numbers.stream()
.map(i -> i.toString())
.collect(Collectors.joining(", "));
Yang ini tidak dapat dikompilasi:
int[] numbers = {1, 2, 3, 4};
String commaSeparatedNumbers = Arrays.stream(numbers)
.map((Integer i) -> i.toString())
.collect(Collectors.joining(", "));
IDEA memberi tahu saya bahwa saya memiliki "String jenis kembalian yang tidak kompatibel dalam ekspresi lambda".
Kenapa? Dan bagaimana cara memperbaikinya?
java
functional-programming
java-8
java-stream
Denys Séguret
sumber
sumber
IntStream
danStream<Integer>
?IntStream
adalah spesialisasi aliran untukint
nilai primitif . AStream<Integer>
hanyalah Arus yang menahanInteger
benda.IntStream
adalah aliran atau primitif (ints) sedangkanSteram<Integer>
aliran objek. Aliran primitif memiliki metode khusus untuk alasan kinerja.IntStream.mapToObj
mengharapkan sebuahIntFunction
, fungsi yang mengkonsumsi suatuint
nilai, oleh karena.mapToObj((Integer i) -> i.toString())
itu tidak berfungsi. Ini tidak akan direkomendasikan karena mengandung konversi yang tidak perlu dariint
menjadiInteger
. Sebaliknya,.mapToObj(Integer::toString)
berfungsi dengan baik karena akan memanggilstatic
metodeInteger.toString(int)
. Perhatikan bahwa ini berbeda dengan memanggil.map(Integer::toString)
aStream<Integer>
karena yang terakhir tidak dapat dikompilasi karena bersifat ambigu..map(Integer::toString)
aStream<Integer>
benar-benar ambigu karena keduanya,.map(i->i.toString())
dan.map(i->Integer.toString(i))
valid. Tapi itu mudah dipecahkan dengan menggunakan.map(Object::toString)
.Arrays.stream(numbers)
membuat diIntStream
bawah tenda dan operasi peta diIntStream
membutuhkanIntUnaryOperator
(yaitu fungsiint -> int
). Fungsi pemetaan yang ingin Anda terapkan tidak menghormati kontrak ini dan karenanya terjadi kesalahan kompilasi.Anda harus menelepon
boxed()
sebelumnya untuk mendapatkanStream<Integer>
(inilahArrays.asList(...).stream()
hasil). Kemudian panggil sajamap
seperti yang Anda lakukan di cuplikan pertama.Perhatikan bahwa jika Anda perlu
boxed()
diikuti olehmap
Anda mungkin ingin menggunakanmapToObj
secara langsung.Keuntungannya adalah
mapToObj
tidak perlu mengemas setiapint
nilai ke suatuInteger
objek; tergantung pada fungsi pemetaan yang Anda terapkan tentunya; jadi saya akan menggunakan opsi ini yang juga lebih pendek untuk ditulis.sumber
Anda dapat membuat Stream Integer menggunakan Arrays.stream (int []), Anda dapat memanggil
mapToObj
sukamapToObj(Integer::toString)
.String csn = Arrays.stream(numbers) // your numbers array .mapToObj(Integer::toString) .collect(Collectors.joining(", "));
Semoga ini membantu..
sumber
Tidak ada tinju, AFAIK, dan tidak ada ledakan string kecil yang ditambahkan ke tumpukan:
public static void main(String[] args) { IntStream stream = IntStream.of(1, 2, 3, 4, 5, 6); String s = stream.collect(StringBuilder::new, (builder, n) -> builder.append(',').append(n), (x, y) -> x.append(',').append(y)).substring(1); System.out.println(s); }
sumber
Jika tujuan dari contoh dan pertanyaan ini adalah untuk mencari tahu bagaimana memetakan string ke aliran int (misalnya, menggunakan aliran int untuk mengakses indeks dalam Array string), Anda juga dapat menggunakan tinju, lalu mentransmisikan ke sebuah int (yang kemudian akan memungkinkan mengakses indeks dari array).
int[] numbers = {0, 1, 2, 3}; String commaSeparatedNumbers = Arrays.stream(numbers) .boxed() .map((Integer i) -> Integer.toString((int)i)) .collect(Collectors.joining(", "));
Panggilan .boxed () mengubah IntStream Anda (aliran int primitif) menjadi Stream (aliran objek - yaitu, objek Integer) yang kemudian akan menerima kembalinya objek (dalam hal ini, objek String) dari lambda Anda. Ini hanya representasi string dari angka untuk tujuan demonstrasi, tetapi bisa juga dengan mudah (dan lebih praktis) objek string apa pun - seperti elemen array string seperti yang disebutkan sebelumnya.
Hanya berpikir saya akan menawarkan kemungkinan lain. Dalam pemrograman, selalu ada banyak cara untuk menyelesaikan suatu tugas. Ketahui sebanyak mungkin yang Anda bisa, lalu pilih salah satu yang paling sesuai untuk tugas yang ada, dengan mempertimbangkan masalah kinerja, intuisi, kejelasan kode, preferensi Anda dalam gaya pengkodean, dan yang paling mendokumentasikan sendiri.
Selamat membuat kode!
sumber
int
- masing ke jenis pembungkusnyaInteger
dan Anda membuka kotaknya setelahnya.