首次问问提问者,请放轻松。 :)无论如何,我不确定使用Java 8流是否可行,但我对学习非常感兴趣。
假设我有以下有序的数字列表:
List<Integer> myList = Arrays.asList(1, 2, 3, 7, 9, 12, 13, 15);
现在,当元素之间的差异大于2时,我想将此列表拆分为多个列表。因此,最终结果将是三个不同的列表:
{1, 2, 3}
{7, 9}
{12, 13, 15}
我可以使用for循环轻松完成此练习,并将当前元素与之前循环时的元素进行比较。但是,我想知道是否有一种使用Java 8流来实现这一目标的简洁方法?就像我之前说的那样,这只是为了我自己对Java 8的学习和理解,所以如果不可能那就没关系。
提前感谢任何意见或答案。
答案 0 :(得分:4)
嗯,我只能想到一个自定义收集器,因为你需要一些以前的状态,但这到目前为止并不简洁(除非你把它隐藏在一个方法后面):
private static <T> Collector<Integer, ?, List<List<Integer>>> diffCollector() {
class Acc {
private Integer previous;
private List<List<Integer>> result = new ArrayList<>();
void accumulate(Integer elem) {
if (previous == null) {
previous = elem;
List<Integer> list = new ArrayList<>();
list.add(previous);
result.add(list);
return;
}
if (elem - previous > 2) {
List<Integer> oneMore = new ArrayList<>();
oneMore.add(elem);
result.add(oneMore);
previous = elem;
} else {
result.get(result.size() - 1).add(elem);
previous = elem;
}
}
Acc combine(Acc other) {
throw new UnsupportedOperationException("Not for parallel");
}
List<List<Integer>> finisher() {
return result;
}
}
return Collector.of(Acc::new, Acc::accumulate, Acc::combine, Acc::finisher);
}
使用方法是:
List<Integer> myList = Arrays.asList(1, 2, 3, 7, 9, 12, 13, 15);
System.out.println(myList.stream().collect(diffCollector()));
答案 1 :(得分:0)
在不创建/实现收藏家和减少行
的情况下即兴创作@Eugene答案 List<Integer> e = Arrays.asList(1,2,3,7,9,12,14,15);
List<Integer> grpMarker = new ArrayList<>();
grpMarker.add(0);
grpMarker.add(0);
Collection<List<Integer>> o = e.stream().collect(Collectors.groupingBy(s-> {
if (s - grpMarker.get(0) > 2) { grpMarker.add(1,grpMarker.get(1)+1); }
grpMarker.remove(0);
grpMarker.add(0,s);
return grpMarker.get(1);
})).values();
System.out.println(o);
grpMarker是启动器,用于跟踪最后一个元素(索引0)和任意组值(索引1)。