I need to parse a string consisting of different integers representing periods when a certain user was or wasn't watching tv.
I start by splitting the string and collecting it into an ArrayList:
final List<String> separated = stream(split(s, "A"))
.map(str -> "A" + str)
.flatMap(str -> stream(split(str, "B")).map(s2 -> s2.startsWith("A") ? s2 : "B" + s2))
collect(Collectors.toList());
The tricky thing comes now. I need to transform those strings into domain objects with from/to
fields.
So, in order to map this properly, my mapping function needs to be aware of the former element. So I did the following:
LocalDateTime temp = initial;
final ArrayList<WatchingPeriod> result = new ArrayList<>();
for (final String s1 : separated) {
final WatchingPeriod period = new WatchingPeriod(temp, temp.plusMinutes(parseLong(substring(s1, 1))),
s1.startsWith("A"));
result.add(period);
temp = period.getTo();
}
return result;
I feel it's a huge step back since I am breaking the whole stream pipeline just in order to get back to the old school for-each.
Is there any way I can do the whole processing in one stream pipeline? I am thinking about creating a custom Collector that would look at the last element in a collection and calculate correct LocalDateTime objects basing on this.
Examples:
input string: "A60B80A60", which means that someone was watching something for 60 minutes, then stopped for 80 and then watched again for 60 minutes
and as a result I'd like to get a List with objects:
1) from: 0:00, to: 1:00, watched: true
2) from: 1:00, to: 2:20, watched: false
3) from: 2:20, to: 3:20, watched: true
calculation of each object requires knowledge about the previous one