问题
Given a String s
and a char c
, I'm curious if there exists some method of producing a List<Integer> list
from s
(where the elements within list
represent the indices of c
within s
).
A close, but incorrect approach would be:
public static List<Integer> 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());
}
The following inputs should yield the following output:
getIndexList("Hello world!", 'l') -> [2, 3, 9]
回答1:
Can be done with IntStream
public static List<Integer> getIndexList(String s, char c) {
return IntStream.range(0, s.length())
.filter(index -> s.charAt(index) == c)
.boxed()
.collect(Collectors.toList());
}
回答2:
Using Java 9, you can iteratively search using the last index as the starting point, and stop when no match is found:
public static List<Integer> 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());
}
Disclaimer: I didn't test this.
回答3:
An alternate in Java9 could be to make use of the iterate(int seed, IntPredicate hasNext,IntUnaryOperator next) as follows:-
private static List<Integer> getIndexList(String word, char c) {
return IntStream
.iterate(word.indexOf(c), index -> index >= 0, index -> word.indexOf(c, index + 1))
.boxed()
.collect(Collectors.toList());
}
回答4:
...Or in java-9:
Stream.of("Hello world!")
.map(Scanner::new)
.flatMap(s -> s.findAll("l"))
.map(mr -> mr.start())
.forEach(System.out::println);
来源:https://stackoverflow.com/questions/48592263/java-8-9-can-a-character-in-a-string-be-mapped-to-its-indices-using-streams