2016-06-25 2 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)을 사용하여 연결할 기본값이 아닌 기본값을 제공하거나 결과 맵에서 매핑을 원하지 않으면 존재하지 않는 매핑을 미리 필터링하여 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))); 
자바 8에서지도의 기본 방법을 사용하여 간단하게 할 수있는
관련 문제