İşte Sotirios Delimanolis'in cevabında bazı varyasyonlar var , ki bu da (+1) ile başlamak için oldukça iyiydi. Aşağıdakileri göz önünde bulundur:
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))));
}
Burada birkaç nokta var. Birincisi jeneriklerde joker karakter kullanımı; bu işlevi biraz daha esnek hale getirir. Örneğin, çıktı haritasının, girdi haritasının anahtarının bir üst sınıfı olan bir anahtara sahip olmasını istiyorsanız bir joker karakter gerekir:
Map<String, String> input = new HashMap<String, String>();
input.put("string1", "42");
input.put("string2", "41");
Map<CharSequence, Integer> output = transform(input, Integer::parseInt);
(Haritanın değerleri için de bir örnek var, ancak gerçekten de anlaşıldı ve Y için sınırlı joker karaktere sahip olmanın sadece kenar durumlarda yardımcı olduğunu itiraf ediyorum.)
İkinci nokta, giriş haritasının üzerinde akışı çalıştırmak yerine, üzerinde entrySetkoştum keySet. Bu, kodu harita girişi yerine haritadan almak zorunda kalmanın pahasına, bence biraz daha temiz hale getirir. Bu arada, başlangıçta key -> keyilk argüman olarak vardı toMap()ve bu bir nedenle bir tür çıkarım hatası ile başarısız oldu. (X key) -> keyÇalıştığı gibi değiştirildi Function.identity().
Yine başka bir varyasyon şöyledir:
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;
}
Bu Map.forEach(), akışlar yerine kullanır . Bu daha da basit, sanırım, çünkü haritalarla kullanmak için biraz sakar olan koleksiyonculara dağılıyor. Bunun nedeni, Map.forEach()anahtar ve değeri ayrı parametreler olarak verirken akış yalnızca bir değere sahiptir - ve anahtarın veya harita girişinin bu değer olarak kullanılıp kullanılmayacağını seçmeniz gerekir. Eksi tarafta, diğer yaklaşımların zengin, akışlı iyiliği yoktur. :-)
e -> e.getKey()ileMap.Entry::getKey. Ama bu bir zevk / programlama tarzı.