2016-06-25 9 views
3

んJava8が便利なことがjava8コンバート地図<X,Y>は+ <X,Z>

Map<X,Y> + Map<Y,Z> = Map<X,Z> 

で、要件の下に実装することができマップする 地図今、私のコードは

ArrayList<String> couponCodes = newArrayList("aaa", "bbb", "ccc"); 
// couponCode -- shopId 
ArrayList<ShopCoupon> shopCoupons = newArrayList(new ShopCoupon("aaa", 1), new ShopCoupon("bbb", 2), new ShopCoupon("ccc", 3)); 
Map<String, Integer> couponCodeShopIdMap = shopCoupons.stream().collect(toMap(sc -> sc.getCouponCode(), sc -> sc.getShopId())); 
// shopId -- name 
ArrayList<Shop> shops = newArrayList(new Shop(1, "zhangsan"), new Shop(2, "lisi"), new Shop(3, "wangwu")); 
Map<Integer, String> shopIdNameMap = shops.stream().collect(toMap(s -> s.getId(), s -> s.getName())); 

//couponCode -- name 
Map<String, String> couponCodeNameMap = couponCodes.stream().collect(toMap(c -> c, c -> shopIdNameMap.get(couponCodeShopIdMap.get(c)))); 
System.out.println(couponCodeNameMap); 

である私が知りたいのいくつかのより便利ですこの要件を実装する方法は?

答えて

7

もう一つの方法は、例えば、直接、最初のマップのエントリセット経由でストリーミングするために、次のようになります。

public static <X, Y, Z> Map<X, Z> join(Map<X, Y> left, Map<Y, Z> right) { 
    return left.entrySet() 
       .stream() 
       .collect(toMap(Map.Entry::getKey, e -> right.get(e.getValue()))); 
} 

値は左のマップに存在していないときに対処するためにあなたが持っている唯一のものです値マップマッパー関数はnullを返すことができないため、右のマップ​​の対応するキーにはNullPointerExceptionがあります。この場合、getOrDefaultを使用して、e -> right.getOrDefault(e.getValue(), defaultValue)を使用して関連付けるnull以外のデフォルト値を指定するか、結果のマップにマッピングしたくない場合は、toMapコレクタをミックスして、存在しないマッピングの先頭をフィルタリングします。

public static <X, Y, Z> Map<X, Z> join(Map<X, Y> left, Map<Y, Z> right) { 
    return left.entrySet().stream().collect(
     HashMap::new, 
     (m, e) -> { 
      //if you still want the mapping k -> null, 
      //you can just use put directly 
      Z value = right.get(e.getValue()); 
      if(value != null) m.put(e.getKey(), value); 
     }, 
     Map::putAll); 
} 
0

あなたは

shopIdNameMap.forEach((key,value)->shopIdNameMap.replace(key,couponCodeNameMap.get(value))); 
のJava 8から地図のデフォルトメソッドを使用して簡単に行うことができます
関連する問題