İş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 entrySet
koş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 -> key
ilk 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ı.