2016-08-12 54 views
1

通過分組我有兩個地圖的Java 8個流/收藏家與地圖

  1. scoreMap<String,Float>具有組名作爲關鍵字及其 得分爲價值具有關鍵和相關的註釋閾值
  2. thresholdMap<Float,String>作爲價值。
  3. 我需要拿出 Map<String,List<String>>這個。閱讀,因爲Map<comment,List of groups its applicable to>Map<group, comment>也很好。

的邏輯是簡單地採取從scorescoresMap,並在threshold地圖比較它threshold。依賴於它的下降(即高於高,高,中,或低於中等之間,挑選從thresholdMap相關評論

大概是這樣的:

BiFunction<Map<String,Float>, Map<Float,String>, Map<String,String>> or 
BiFunction<Map<String,Float>, Map<Float,String>, Map<String,List<String>>> 

我還沒有想出如何使用Predicate,檢查三個條件做groupingBy,所以道歉,不爲別的,樣品Stream代碼非流代碼看起來像這樣(不使用地圖):

if(orgScorePct >= HI_THRESHOLD) 
    return "ORG_HI_SCORE_COMMENT"; 
if(orgScorePct < HI_THRESHOLD && orgScorePct > MED_THRESHOLD) 
    return "ORG_MED_SCORE_COMMENT"; 
return "ORG_LOW_SCORE_COMMENT"; 

回答

2

首先,這將是一個很大的EAS更適合使用TreeMap作爲閾值:由於它是按鍵上的排序映射,因此爲給定值確定正確的閾值註釋只需獲取該值的floorEntry即可。最高限額條目對應於具有低於給定值的鍵的條目。類似地,有ceilingEntry來檢索具有密鑰的條目,只是在給定的條目之後。

考慮到這一點,我們可以有以下的(樣本數據):

Map<String,Float> scoreMap = new HashMap<>(); 
TreeMap<Float,String> thresholdMap = new TreeMap<>(); 

scoreMap.put("name1", 1.0f); 
scoreMap.put("name2", 2.0f); 
scoreMap.put("name3", 3.0f); 
scoreMap.put("name4", 5.0f); 

thresholdMap.put(0.5f, "comment0"); 
thresholdMap.put(1.5f, "comment1"); 
thresholdMap.put(4.5f, "comment2"); 

Map<String,List<String>> result = 
    scoreMap.entrySet() 
      .stream() 
      .collect(Collectors.groupingBy(
       e -> thresholdMap.floorEntry(e.getValue()).getValue(), 
       Collectors.mapping(Map.Entry::getKey, Collectors.toList()) 
      )); 

這導致{comment2=[name4], comment1=[name3, name2], comment0=[name1]}它是正確的:的"comment2"所述閾值是4.5,僅具有得分大於;的"comment1"門檻是1.5和兩個"name2""name3"有1.5和4.5之間的分數,等

要小心,如果沒有樓層入:它可能是一個分數不具有相應的閾值的情況;例如,在上面的數據中,0分會導致問題。要處理這種情況,您需要檢查floorEntry是否返回null並通過返回默認值來相應地處理它。

+0

感謝@ Tunaki的出色答案,我想我還會寫下另一個選項,我想要爲需要它的任何人獲取Map :BiFunction , \t \t \t \t TreeMap的<浮點,字符串>, \t \t \t \t \t地圖<字符串,字符串>> buildGroupComments2 =(A,B) - > A.entrySet()流()收集(收集器。toMap( \t \t \t \t \t \t \t \t \t \t \t \t \t \t \t \t \t \t \t \t E-> e.getKey(),E-> B.floorEntry(e.getValue())。的getValue()) );' – aaaaarrrgghhh

0
List<BeanClass> list1 = new ArrayList<BeanClass>(); 
    DateFormat formatter = new SimpleDateFormat("yyyy-MM-dd"); 
    list1.add(new BeanClass(123,abc,99.0,formatter.parse("2018-02-01"))); 
    list1.add(new BeanClass(456,xyz,99.0,formatter.parse("2014-01-01"))); 
    list1.add(new BeanClass(789,pqr,95.0,formatter.parse("2014-01-01"))); 
    list1.add(new BeanClass(1011,def,99.0,formatter.parse("2014-01-01"))); 
    Map<Object, Optional<Double>> byDate = list1.stream() 
    .collect(Collectors.groupingBy(p -> formatter.format(p.getCurrentDate()), 
    Collectors.mapping(BeanClass::getAmount, Collectors.maxBy(Double::compare)))); 
+2

雖然這段代碼可能回答這個問題,但提供關於它如何解決問題的額外解釋會提高答案的長期價值。 – Norrius