Reputation: 289
I have the following nested list:
List<List<String>> nestedList = new ArrayList<>();
nestedList.add(Arrays.asList("aM0", "b"));
nestedList.add(Arrays.asList("c", "aM0"));
I want to remove "M0" from all the strings. I want to challenge myself using Java 8 stream. The following is what I wrote:
nestedList.stream()
.map(t -> t.stream()
.map(s -> s.substring(0, s.indexOf('M')))
.collect(Collectors.toCollection(ArrayList::new)))
.collect(Collectors.toList());
But JDK throws a lot of exceptions. Can anyone tell me how to fix? Or we can not use streams in this special situation? Thank you.
Upvotes: 0
Views: 664
Reputation: 17289
The other simple way is use replaceAll(UnaryOperator operator)
nestedList.forEach(list->list.replaceAll(s -> s.replace("M0", "")));
Upvotes: 1
Reputation: 289
Thank you for quickly spotting the issue. Since after marker 'M', it may not be just '0', I change the code as follows, and it now works:
nestedList.stream().map(t->t.stream().map(s->s.contains("M") ? s.substring(0, s.indexOf('M')) : s).collect(Collectors.toCollection(ArrayList<String>::new))).collect(Collectors.toList());
Thank you very much for your time to answer my question!
Upvotes: 0
Reputation: 59950
Your real problem is with String::substring
so when you use for example :
String str = "b";
str = str.substring(0, str.indexOf('M'));
this will throws :
java.lang.StringIndexOutOfBoundsException: begin 0, end -1, length 1
because str.indexOf('M')
return -1
if there is no such occurrence (String::indexOf
) so str.substring(0, -1)
will fail with that error
Instead in such situations its better to use String::replace
like so :
nestedList = nestedList.stream()
.map(t -> t.stream()
.map(s -> s.replace("M0", ""))
.collect(Collectors.toList())
).collect(Collectors.toList());
Outputs
[[a, b], [c, a]]
Upvotes: 4