First time question asker here so please go easy on me. :) Anyway, I am not sure if this is possible using a Java 8 stream but I am very interested in learning.
Let's say I have the following ordered list of numbers:
List<Integer> myList = Arrays.asList(1, 2, 3, 7, 9, 12, 13, 15);
Now, I want to split this list into multiple lists when the difference between elements is greater than 2. Therefore, the end result would be three different lists:
{1, 2, 3}
{7, 9}
{12, 13, 15}
I could easily do this exercise using a for loop and comparing the current element to the previous while looping. However, I am wondering if there is a concise way to accomplish this using a Java 8 stream? Like I said before, this is only for my own learning and understanding of Java 8 so if it isn't possible then that's okay.
Thanks in advance for any comments or answers.
Well I can only think of a custom collector, since you need some previous state, but this is by far not concise (unless you hide it behind a method):
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);
}
And usage would be:
List<Integer> myList = Arrays.asList(1, 2, 3, 7, 9, 12, 13, 15);
System.out.println(myList.stream().collect(diffCollector()));