任务是返回带有每个字母之和的String
。输入也是一个String
。
例如
input: dasamdw
output: s1d2a2m1w1
我想出了一个简单的快速算法:
private String method(String input) {
Map<String, Integer> integerMap = new HashMap<>();
for( char c : input.toCharArray()) {
String key = String.valueOf(c);
if(integerMap.containsKey(key)) {
integerMap.put(key, integerMap.get(key) + 1);
} else {
integerMap.put(key, 1);
}
}
StringBuilder sb = new StringBuilder();
for(Map.Entry<String, Integer> e : integerMap.entrySet()) {
sb.append(e.getKey());
sb.append(e.getValue());
}
return sb.toString();
}
但我真的很想使用流来实现这一点,例如:
private String method(String input) {
Map<Character, Integer> collect =
input.chars().
mapToObj(i -> (char)i).collect(Collectors.groupingBy(Function.identity(), Collectors.counting() ));
return collect.entrySet()
.stream()
.map(entry -> entry.getKey() + "" + entry.getValue())
.collect(Collectors.joining(""));
}
但我无法找出正确的 groupingBy
部分...
最佳答案
请注意,甚至您的循环版本也可以简化
private String method(String input) {
Map<Character, Integer> integerMap = new HashMap<>();
for(char c: input.toCharArray()) {
integerMap.merge(c, 1, Integer::sum);
}
StringBuilder sb = new StringBuilder();
for(Map.Entry<Character, Integer> e : integerMap.entrySet()) {
sb.append(e.getKey()).append(e.getValue());
}
return sb.toString();
}
这并不是最糟糕的解决方案。使用 Java 8 并不意味着将所有内容都转换为 Stream API 使用。
您可以使用这样的 Stream 解决方案。
private String method(String input) {
return input.chars().boxed()
.collect(Collectors.groupingBy(Function.identity(), Collectors.counting()))
.entrySet().stream()
.map(e -> Character.toString((char)e.getKey().intValue())+e.getValue())
.collect(Collectors.joining());
}
但请注意,最简单的解决方案并不总是最有效的解决方案,例如对于大字符串,以下解决方案可能更可取:
private String method(String input) {
IntSummaryStatistics ss = input.chars().summaryStatistics();
int min = ss.getMin();
int[] counts = new int[ss.getMax()-min+1];
input.chars().forEach(c -> counts[c-min]++);
return IntStream.range(0, counts.length)
.filter(ix -> counts[ix] > 0)
.collect(StringBuilder::new,
(sb,c)->sb.append((char)(c+min)).append(counts[c]),
StringBuilder::append)
.toString();
}
与其他解决方案相比,除了避免开销之外,它还返回本质上排序的结果。
产生排序结果的另一种选择是
private String method(String input) {
char[] array = input.toCharArray();
Arrays.sort(array);
StringBuilder sb = new StringBuilder();
for(int ix = 0, e; ix<array.length; ix = e) {
char c = array[ix];
for(e = ix+1; e<array.length && array[e]==c; ) e++;
sb.append(c).append(e-ix);
}
return sb.toString();
}
关于java - 如何将特定算法与流进行转换,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47722206/