Saya ingin menerjemahkan Daftar objek ke dalam Peta menggunakan aliran Java 8 dan lambdas.
Ini adalah bagaimana saya akan menulisnya di Java 7 dan di bawah.
private Map<String, Choice> nameMap(List<Choice> choices) {
final Map<String, Choice> hashMap = new HashMap<>();
for (final Choice choice : choices) {
hashMap.put(choice.getName(), choice);
}
return hashMap;
}
Saya dapat melakukannya dengan mudah menggunakan Java 8 dan Jambu tetapi saya ingin tahu bagaimana melakukan ini tanpa Jambu.
Dalam jambu biji:
private Map<String, Choice> nameMap(List<Choice> choices) {
return Maps.uniqueIndex(choices, new Function<Choice, String>() {
@Override
public String apply(final Choice input) {
return input.getName();
}
});
}
Dan Jambu biji dengan Java 8 lambdas.
private Map<String, Choice> nameMap(List<Choice> choices) {
return Maps.uniqueIndex(choices, Choice::getName);
}
java
lambda
java-8
java-stream
Tom Cammann
sumber
sumber
Maps.uniqueIndex(choices, Choice::getName)
.Seq
dari perpustakaan JOOL (yang saya sarankan kepada siapa pun yang menggunakan Java 8), Anda juga dapat meningkatkan singkatnya dengan:seq(choices).toMap(Choice::getName)
it -> it
diri saya sendiri.Function.identity()
digunakan di sini sebagian besar karena itu digunakan dalam dokumentasi yang direferensikan dan hanya itu yang saya ketahui tentang lambdas pada saat penulisanJika kunci Anda TIDAK dijamin unik untuk semua elemen dalam daftar, Anda harus mengonversinya menjadi
Map<String, List<Choice>>
aMap<String, Choice>
sumber
Multimaps
metode jambu biji pilihan yang lebih baik? Ini bisa menjadi ketidaknyamanan karena tidak mengembalikanMap
Obyek.Gunakan
getName()
sebagai kunci danChoice
itu sendiri sebagai nilai peta:sumber
Collectors.toMap(Choice::getName,c->c)
(2 chars lebih pendek)choices.stream().collect(Collectors.toMap(choice -> choice.getName(),choice -> choice));
fungsi pertama untuk kunci, fungsi kedua untuk nilaic -> c
tetapiFunction.identity()
membawa lebih banyak informasi semantik. Saya biasanya menggunakan impor statis sehingga saya bisa menggunakannyaidentity()
Berikut ini satu lagi jika Anda tidak ingin menggunakan Collectors.toMap ()
sumber
Collectors.toMap()
atau HashMap kita sendiri seperti yang Anda tunjukkan dalam contoh di atas?Sebagian besar jawaban yang tercantum, ketinggalan kasus ketika daftar memiliki item duplikat . Dalam hal itu ada jawaban akan melempar
IllegalStateException
. Lihat kode di bawah ini untuk menangani duplikat daftar juga:sumber
sumber
Misalnya, jika Anda ingin mengonversi bidang objek ke peta:
Contoh objek:
Dan operasi konversi Daftar Ke Peta:
sumber
Jika Anda tidak keberatan menggunakan perpustakaan pihak ketiga, cyclop-react lib (pengungkapan Saya adalah kontributor) AOL memiliki ekstensi untuk semua jenis Koleksi JDK , termasuk Daftar dan Peta .
sumber
Saya mencoba melakukan ini dan menemukan bahwa, menggunakan jawaban di atas, ketika menggunakan
Functions.identity()
untuk kunci Peta, maka saya memiliki masalah dengan menggunakan metode lokal sukathis::localMethodName
benar-benar bekerja karena masalah pengetikan.Functions.identity()
sebenarnya melakukan sesuatu pada pengetikan dalam kasus ini sehingga metode hanya akan bekerja dengan mengembalikanObject
dan menerima paramObject
Untuk mengatasi ini, saya akhirnya membuang
Functions.identity()
dan menggunakans->s
saja.Jadi kode saya, dalam kasus saya untuk mendaftar semua direktori di dalam direktori, dan untuk masing-masing menggunakan nama direktori sebagai kunci untuk peta dan kemudian memanggil metode dengan nama direktori dan mengembalikan koleksi item, terlihat seperti:
sumber
Anda dapat membuat Stream indeks menggunakan IntStream dan kemudian mengonversinya menjadi Peta:
sumber
Saya akan menulis bagaimana mengkonversi daftar ke peta menggunakan generik dan inversi kontrol . Hanya metode universal!
Mungkin kita memiliki daftar Integer atau daftar objek. Jadi pertanyaannya adalah sebagai berikut: apa yang harus menjadi kunci peta?
buat antarmuka
sekarang menggunakan inversi kontrol:
Sebagai contoh, jika kita memiliki objek buku, kelas ini adalah untuk memilih kunci untuk peta
sumber
Saya menggunakan sintaks ini
sumber
groupingBy
menciptakanMap<K,List<V>>
, bukan aMap<K,V>
.String getName();
(bukan Integer)sumber
Ini bisa dilakukan dengan 2 cara. Biarkan orang menjadi kelas yang akan kita gunakan untuk menunjukkannya.
Biarkan orang menjadi daftar Orang yang akan dikonversi ke peta
1.Menggunakan Simple foreach dan Ekspresi Lambda pada Daftar
2.Menggunakan Kolektor pada Streaming yang ditentukan pada Daftar yang diberikan.
sumber
Dimungkinkan untuk menggunakan stream untuk melakukan ini. Untuk menghapus kebutuhan untuk menggunakan secara eksplisit
Collectors
, impor mungkin dilakukantoMap
secara statis (seperti yang disarankan oleh Java Efektif, edisi ketiga).sumber
Berikut ini solusi dari StreamEx
sumber
Bahkan melayani tujuan ini untukku,
sumber
Jika setiap nilai baru untuk nama kunci yang sama harus diganti:
Jika semua pilihan harus dikelompokkan dalam daftar untuk suatu nama:
sumber
sumber
Sebagai alternatif, Anda
guava
dapat menggunakan kotlin-stdlibsumber
Kunci publikasikan AA {12 = ASDFASDFASDF, 7 = EEDDDAD, 4 = CCCC, 3 = BBB, 2 = AA}
sumber