2017-08-02 83 views
1

我有Map對象看起來像這樣的列表:Java集合減少到地圖

year => 2016, 
month => 10, 
day => 11, 
count => 123 

我每天在startDate < endDate範圍內的元素。

我希望能夠根據startDateendDate之間的間隔將這些元素縮減爲不同的時間分組。如果startDateendDate之間的差距大於4年,我想將它們分組到幾年。如果差距小於四年,但大於一年,我想將它們分成幾個月。如果不到一年,但超過一個月,我想分成幾個星期。任何不到一個月的時間,都不需要分組。

當我說「組」我的意思是我要總結爲屬於某一特定年份的一切count元素(使用上面的第一個例子),並返回一個地圖,每年像這樣的:

year => 2016, 
month => 1 
day => 1 
count => 9897 

我知道必須有完成這個優雅的方式,但我有困難的時候,我的包裹左右腦的邏輯。

+6

如果差異在1到4年之間,你說你想按月分組元素,但是如何?即如果你有兩年的數據,例如。 2015年和2016年,您是否想要將1月份的所有元素合併到一個小組中,無論是一年,還是您希望2015年1月和2016年1月分開小組?同樣的問題幾個星期等 –

+7

告訴我們一些努力 - 你到目前爲止嘗試過什麼? – bartektartanus

+0

@FedericoPeraltaSchaffner我基本上想把所有的東西都捲成一整年,一個月或一週的一個元素。 – daniel0mullins

回答

2

我不明白這一點,你可以簡單地做:

if(starDate is smaller then endDate by 4 year) { 

       resultMap = yourList.stream() 
         .collect(Collectors.groupingBy(map.get("year"), 
          Collectors.summingInt(map.get("count"))); 

} 

else if(starDate is... another condition) { 
     resultMap = yourList.stream() 
         .collect(Collectors.groupingBy(map.get("month"), 
          Collectors.summingInt(map.get("count"))); 

} 

// all the there cases... 

後來映射這個結果到任何你想要的。

2

照常使用Collectors.groupingBy,並提供您想要的分類器。

final LocalDate endDate = dateCounts.last().getDate(); 
Function<DateCount, LocalDate> mapLocalDate = dc-> { 
    LocalDate ld = dc.getDate(); 
    long m = Period.between(ld, endDate).toTotalMonths(); 
    if (m > 4*12) { 
     return ld.withMonth(1).withDayOfMonth(1); 
    } else if (m >= 1) { 
     return ld.withDayOfMonth(1); 
    } else { 
     return ld; 
    } 
}; 
Map<LocalDate, Long> r = dateCounts.stream() 
.collect(Collectors.groupingBy(
     mapLocalDate, 
     TreeMap::new, 
     Collectors.summingLong(DateCount::getCount) 
    ) 
); 
System.out.println( "EndDate = " + endDate); 
System.out.println( r);