Berikut adalah beberapa variasi jawaban Sotirios Delimanolis , yang cukup baik untuk memulai dengan (+1). Pertimbangkan yang berikut ini:
static <X, Y, Z> Map<X, Z> transform(Map<? extends X, ? extends Y> input,
Function<Y, Z> function) {
return input.keySet().stream()
.collect(Collectors.toMap(Function.identity(),
key -> function.apply(input.get(key))));
}
Beberapa poin di sini. Pertama adalah penggunaan wildcard dalam obat generik; ini membuat fungsinya agak lebih fleksibel. Wildcard akan diperlukan jika, misalnya, Anda ingin peta keluaran memiliki kunci yang merupakan superclass dari kunci peta input:
Map<String, String> input = new HashMap<String, String>();
input.put("string1", "42");
input.put("string2", "41");
Map<CharSequence, Integer> output = transform(input, Integer::parseInt);
(Ada juga contoh untuk nilai-nilai peta, tetapi ini benar-benar dibuat-buat, dan saya akui bahwa memiliki wildcard terbatas untuk Y hanya membantu dalam kasus tepi.)
Poin kedua adalah bahwa alih-alih menjalankan streaming di atas peta input entrySet
, saya malah menjalankannya di atas keySet
. Ini membuat kode sedikit lebih bersih, saya pikir, dengan biaya harus mengambil nilai dari peta alih-alih dari entri peta. Kebetulan, saya awalnya memiliki key -> key
argumen pertama toMap()
dan ini gagal dengan kesalahan inferensi jenis karena beberapa alasan. Mengubahnya (X key) -> key
berfungsi, seperti yang terjadi Function.identity()
.
Variasi lain adalah sebagai berikut:
static <X, Y, Z> Map<X, Z> transform1(Map<? extends X, ? extends Y> input,
Function<Y, Z> function) {
Map<X, Z> result = new HashMap<>();
input.forEach((k, v) -> result.put(k, function.apply(v)));
return result;
}
Ini menggunakan Map.forEach()
bukannya stream. Ini bahkan lebih sederhana, saya pikir, karena itu dibagikan kepada kolektor, yang agak canggung untuk digunakan dengan peta. Alasannya adalah bahwa Map.forEach()
memberikan kunci dan nilai sebagai parameter terpisah, sedangkan aliran hanya memiliki satu nilai - dan Anda harus memilih apakah akan menggunakan kunci atau entri peta sebagai nilai itu. Di sisi minusnya, ini tidak memiliki kekayaan, aliran kebaikan dari pendekatan lain. :-)
e -> e.getKey()
denganMap.Entry::getKey
. Tapi itu masalah selera / gaya pemrograman.