【发布时间】:2022-01-20 07:38:52
【问题描述】:
给定一个字符串,需要一个列表映射,其中键是每个字符,值是整数列表,指示字符所在的索引。\ 我想在 Java 8 中做到这一点
输入:standard
输出:
s - 0
t - 1
a - 2,5
n - 3
d - 4,7
r - 6
【问题讨论】:
标签: java string lambda java-8 java-stream
给定一个字符串,需要一个列表映射,其中键是每个字符,值是整数列表,指示字符所在的索引。\ 我想在 Java 8 中做到这一点
输入:standard
输出:
s - 0
t - 1
a - 2,5
n - 3
d - 4,7
r - 6
【问题讨论】:
标签: java string lambda java-8 java-stream
您可以使用的一个巧妙技巧是流式传输字符串的索引,然后按该索引处的字符收集它们:
Map<Character, List<Integer>> indices =
IntStream.range(0, input.length())
.boxed()
.collect(Collectors.groupingBy(input::charAt));
【讨论】:
为了保持插入顺序,在按字符对索引进行分组时必须使用LinkedHashMap:
String input = "standard";
Map<Character, List<Integer>> charIndexes =
IntStream.range(0, input.length())
.boxed()
.collect(Collectors.groupingBy(
input::charAt, LinkedHashMap::new, Collectors.toList()
));
不使用 Stream API 的类似解决方案:
Map<Character, List<Integer>> charIndexes = new LinkedHashMap<>();
for (int i = 0, n = input.length(); i < n; i++) {
charIndexes.computeIfAbsent(input.charAt(i), k -> new ArrayList<>()).add(i);
}
那么地图的内容可能会这样打印:
charIndexes.forEach((c, ix) -> System.out.println(
c + " - " + ix.stream().map(String::valueOf).collect(Collectors.joining(","))
));
输出
s - 0
t - 1
a - 2,5
n - 3
d - 4,7
r - 6
【讨论】: