chr*_*.fy 2 java java-8 java-stream
我有一个unix时间戳列表,例如:
[1111111 1200000 1200060 1200120 1200180 1300000 1400000 140060]
Run Code Online (Sandbox Code Playgroud)
我希望按照彼此60秒内的簇对它们进行分组,其中键是第一个时间戳,例如:
{1111111=[1111111], 1200000=[1200000,120060, 1200120], 1300000=[1300000], 1400060=[1400000, 1400060]}
Run Code Online (Sandbox Code Playgroud)
我通过使用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);
Run Code Online (Sandbox Code Playgroud)
为了执行此操作,您需要对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);
Run Code Online (Sandbox Code Playgroud)
结果与您的问题中的数据:
{1200000=[1200000, 1200060, 1200120, 1200180], 1300000=[1300000], 1400000=[1400000, 1400060], 1111111=[1111111]}
Run Code Online (Sandbox Code Playgroud)
该方法groupRuns将所有与给定谓词匹配的连续元素分组,并List默认将所有这些元素收集到一个元素中.在这种情况下,列表的第一个元素将是最终Map的键,列表本身将是值.
| 归档时间: |
|
| 查看次数: |
148 次 |
| 最近记录: |