英文:
Collect String to LinkedHashMap <Character, Integer> , with frequency of characters
问题
这是我修改后的代码:
private Map<Character, Integer> countSymbols(String sentence) {
return sentence.chars()
.mapToObj(c -> (char) c)
.collect(Collectors.toMap(
Function.identity(),
c -> 1,
Integer::sum,
LinkedHashMap::new));
}
英文:
I need to collect a sentence to a map using stream, where the key is a character (the order should be like this: the first letter in the sentence is the first in the map, so I choose LinkedHashMap ), and the value is counter which shows the frequency of repeating the same character.
> Example input: hello world
> Example output: h=1 , e=1, l=3, o=2, w=1 , r=1, d=1
There is my code, and I can`t understand what is the problem.
private Map<Character, Integer> countSymbols(String sentence) {
return sentence.chars()
.collect(Collectors.toMap(key -> (Character) key,
counter -> 1,
Integer::sum,
LinkedHashMap::new));
}
答案1
得分: 3
String.chars()
返回一个 IntStream
,表示原始的 int
流,无法使用 Collectors.toMap
进行收集。
你可以将其映射为一个 Character
对象,一旦完成映射,你可以使用 Collectors.grouping
来完成繁重的工作,而不是实现它的逻辑:
private Map<Character, Long> countSymbols(String sentence) {
return sentence.chars()
.mapToObj(c -> (char) c)
.collect(Collectors.groupingBy(Function.identity(),
Collectors.counting()));
}
编辑:
Collectors.grouping
不保留流的顺序,所以你确实需要像你之前做的那样手动实现它。
mapToObj
调用仍然是必需的,如果你想避免在示例中 "hello" 和 "world" 之间计算空格,你需要添加一个 filter
调用:
private Map<Character, Integer> countSymbols(String sentence) {
return sentence.chars()
.filter(Character::isAlphabetic)
.mapToObj(c -> (char) c)
.collect(Collectors.toMap(Function.identity(),
counter -> 1,
Integer::sum,
LinkedHashMap::new));
}
英文:
String.chars()
returns an IntStream
(i.e., a stream of primitieve int
s), that can't be collected with Collectors.toMap
.
You could map it to a Character
object, and once you've done so, you could use Collectors.grouping
to do the heavy lifting instead of implementing its logic:
private Map<Character, Long> countSymbols(String sentence) {
return sentence.chars()
.mapToObj(c -> (char) c)
.collect(Collectors.groupingBy(Function.identity(),
Collectors.counting()));
}
EDIT:<br/>
Collectors.grouping
does not retain the order of the stream, so you'll really have to implement it manually as you've done.
the mapToObj
call is still required, and if you want to avoid counting the space between "hello" and "world" in the example, you need to add a filter
call:
private Map<Character, Integer> countSymbols(String sentence) {
return sentence.chars()
.filter(Character::isAlphabetic)
.mapToObj(c -> (char) c)
.collect(Collectors.toMap(Function.identity(),
counter -> 1,
Integer::sum,
LinkedHashMap::new));
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论