Java 8/9:String中的字符是否可以映射到其索引(使用流)?

给定一个String s和一个char c ,我很好奇是否存在一些从s生成List list s (其中list中的元素表示sc的索引)。

一个接近但不正确的方法是:

 public static List getIndexList(String s, char c) { return s.chars() .mapToObj(i -> (char) i) .filter(ch -> ch == c) .map(s::indexOf) // Will obviously return the first index every time. .collect(Collectors.toList()); } 

以下输入应产生以下输出:

 getIndexList("Hello world!", 'l') -> [2, 3, 9] 

可以使用IntStream完成

 public static List getIndexList(String s, char c) { return IntStream.range(0, s.length()) .filter(index -> s.charAt(index) == c) .boxed() .collect(Collectors.toList()); } 

使用Java 9,您可以使用最后一个索引作为起始点进行迭代搜索,并在找不到匹配项时停止:

 public static List getIndexList(String s, char c) { return IntStream.iterate(s.indexOf(c), i -> s.indexOf(c, i + 1)) .takeWhile(i -> i > -1) .boxed() .collect(Collectors.toList()); } 

免责声明:我没有测试过这个。

Java9中的替代方法可能是使用iterate(int seed, IntPredicate hasNext,IntUnaryOperator next) ,如下所示:

 private static List getIndexList(String word, char c) { return IntStream .iterate(word.indexOf(c), index -> index >= 0, index -> word.indexOf(c, index + 1)) .boxed() .collect(Collectors.toList()); } 

……或者在java-9中:

 Stream.of("Hello world!") .map(Scanner::new) .flatMap(s -> s.findAll("l")) .map(mr -> mr.start()) .forEach(System.out::println);