我有一个unix时间戳列表,例如:
[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);
答案 0 :(得分: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的键,列表本身将是值。