我有以下嵌套列表:
List<List<String>> nestedList = new ArrayList<>();
nestedList.add(Arrays.asList("aM0", "b"));
nestedList.add(Arrays.asList("c", "aM0"));
我想从所有字符串中删除“ M0”。我想使用Java 8流来挑战自己。以下是我写的内容:
nestedList.stream()
.map(t -> t.stream()
.map(s -> s.substring(0, s.indexOf('M')))
.collect(Collectors.toCollection(ArrayList::new)))
.collect(Collectors.toList());
但是JDK抛出了很多异常。谁能告诉我如何解决?还是在这种特殊情况下我们不能使用流?谢谢。
答案 0 :(得分:4)
您真正的问题是String::substring
,所以当您使用例如:
String str = "b";
str = str.substring(0, str.indexOf('M'));
这会抛出:
java.lang.StringIndexOutOfBoundsException: begin 0, end -1, length 1
因为str.indexOf('M')
如果没有发生(String::indexOf
,则返回-1
,因此str.substring(0, -1)
将因该错误而失败
在这种情况下,最好像这样使用String::replace
:
nestedList = nestedList.stream()
.map(t -> t.stream()
.map(s -> s.replace("M0", ""))
.collect(Collectors.toList())
).collect(Collectors.toList());
输出
[[a, b], [c, a]]
答案 1 :(得分:1)
另一种简单的方法是使用replaceAll(UnaryOperator operator)
nestedList.forEach(list->list.replaceAll(s -> s.replace("M0", "")));
答案 2 :(得分:0)
感谢您快速发现问题。由于在标记“ M”之后,它可能不只是“ 0”,因此我将代码更改如下,并且现在可以使用了:
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());
非常感谢您抽出宝贵时间回答我的问题!