I don't believe this easily lends itself to streams. Nor would a stream approach be any more clear in expressing the problem statement than a simple loop.
As long as you don't care what order the sublists are in, it is pretty straight forward using List.lastIndexOf
and a while loop
. Note that since this chews up the original list and the fact that these sublists don't overlap, there is no chance of the sublists being altered by changes to the original list or by each other (unless a reference to the original exists). But one can always pass the sublist
as an argument to the ArrayList
constructor if this is a concern.
List<String> names = new ArrayList<>(List.of("Tom", "louis",
"martha", "Tom", "john", "Carol", "Tom", "Simon"));
List<List<String>> lists = new ArrayList<>();
int start;
while ((start = names.lastIndexOf("Tom")) >= 0) {
ists.add(names.subList(start, names.size()));
names = names.subList(0, start);
}
lists.forEach(System.out::println);
Prints
[Tom, Simon]
[Tom, john, Carol]
[Tom, louis, martha]
Note that the order can be reversed by specifying an index of 0
in the add
method. But that can be expensive for ArrayLists
due to the copying. A LinkedList
would alleviate that expense for a bit of overhead.
And just for completion, here is my stream solution.
- first, stream the names in successive
sublists
based on where Tom
is located. So the first list contains all the names, the second, all but the last "Tom"
grouping, and so forth.
- Then for each of those sublists, pick off the last sublist starting with
Tom
from the end.
- and put the lists in a collection.
List<List<String>> result = Stream.iterate(
names,
n -> n.size() > 0 && n.lastIndexOf("Tom") >= 0,
n -> n.subList(0, n.lastIndexOf("Tom")))
.map(n -> n.subList(n.lastIndexOf("Tom"), n.size()))
.collect(Collectors.toList());
result.forEach(System.out::println);
Prints
[Tom, Simon]
[Tom, john, Carol]
[Tom, louis, martha]
I still prefer the while loop solution as I think it is cleaner and more succinct. Someone more proficient in streams could probably do it better.