Java 8/9:String中的字符是否可以映射到其索引(使用流)?
给定一个String s
和一个char c
,我很好奇是否存在一些从s
生成List list
s
(其中list
中的元素表示s
中c
的索引)。
一个接近但不正确的方法是:
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);