使用Java 8流来转换嵌套集合

时间:2018-06-19 17:28:40

标签: java java-8 java-stream

我有以下嵌套列表:

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抛出了很多异常。谁能告诉我如何解决?还是在这种特殊情况下我们不能使用流?谢谢。

3 个答案:

答案 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());

非常感谢您抽出宝贵时间回答我的问题!