2016-02-01 97 views
2

我有UNIX的列表組的條目的時間戳,例如:爪哇8流通過數值接近

[1111111 1200000 1200060 1200120 1200180 1300000 1400000 140060] 

我想將它們組由簇其中在彼此的60秒內的鍵是所述第一時間戳,如:

{1111111=[1111111], 1200000=[1200000,120060, 1200120], 1300000=[1300000], 1400060=[1400000, 1400060]} 

我以一個for循環來實現這一點,我希望有這樣做最好使用Java 8流的更好的方法。

(我不是偉大與Java等,如果有不使用流的方式,有沒有更好的構建for循環?)

List <Integer> timestamps = new ArrayList<Integer>(); 
timestamps.add(1111111); 
timestamps.add(1200000); 
timestamps.add(1200060); 
timestamps.add(1200120); 
timestamps.add(1200180); 
timestamps.add(1300000); 
timestamps.add(1400000); 
timestamps.add(1400060); 

HashMap <Integer, List <Integer>> grouped = new HashMap<Integer, List <Integer>>(); 

List <Integer> subList = new ArrayList<Integer>(); 

for (int i = 0; i < timestamps.size(); i++) { 
    if(i > 0 && (timestamps.get(i - 1) + 60 < timestamps.get(i))) { 
     grouped.put(subList.get(0), new ArrayList <Integer>(subList)); 
     subList.removeAll(subList); 
    } 
    subList.add(timestamps.get(i)); 
} 
grouped.put(subList.get(0), subList); 

回答

5

爲了做到這一點操作,您需要對與謂詞相匹配的Stream上的連續元素進行操作。不幸的是,目前沒有使用Stream API輕鬆實現目標的標準方法。

StreamEx庫爲此工具提供groupRuns操作。考慮到列表已經排序(否則,您可以通過調用sorted()排序的話),你可以有:

Map<Integer, List<Integer>> map = 
    StreamEx.of(timestamps) 
      .groupRuns((t1, t2) -> t2 - t1 <= 60) 
      .toMap(l -> l.get(0), l -> l); 

結果與你的問題的數據:

{1200000=[1200000, 1200060, 1200120, 1200180], 1300000=[1300000], 1400000=[1400000, 1400060], 1111111=[1111111]} 

的方法groupRuns組中的所有連續匹配給定謂詞並將所有這些元素默認收集到List中的元素。在這種情況下,列表的第一個元素將成爲最終Map的關鍵字,而列表本身將成爲值。

+0

謝謝!我還沒有機會嘗試這個圖書館,但我可以看到它確實需要什麼。 –

+0

可惜流API不支持它 –