Java 使用流将字符串中的字母映射到出现次数
我有一个字符串Java 使用流将字符串中的字母映射到出现次数,java,lambda,java-stream,Java,Lambda,Java Stream,我有一个字符串s,我正在尝试使用流API将s中的每个字母映射到它在s中出现的次数。 例如,长颈鹿->{1,1,1,1,2,2,1} 我尝试使用的代码是: String s = "giraffe"; int[] occurences = s.chars().map(c -> count(s, c)).toArray(); public int count(String text, char ch) { return (int) text.chars().filt
s
,我正在尝试使用流API将s
中的每个字母映射到它在s
中出现的次数。例如,
长颈鹿->{1,1,1,1,2,2,1}
我尝试使用的代码是:
String s = "giraffe";
int[] occurences = s.chars().map(c -> count(s, c)).toArray();
public int count(String text, char ch) {
return (int) text.chars().filter(c -> c == ch).count();
}
但是我得到了不兼容的类型:在以int[]occurrences=…
我试过一些不同的变体,但都不起作用。有什么想法吗?谢谢我修改了您的
count
方法,以接受int
,而不是char
,它可以工作
import java.util.Arrays;
class Main {
public static void main(String[] args) {
String s = "giraffe";
int[] occurences = s.chars().map(c -> count(s, c)).toArray();
System.out.println(Arrays.toString(occurences));
}
public static int count(String text, int ch) {
return (int) text.chars().filter(c -> c == ch).count();
}
}
请参见使用循环,我会这样做
- 分配一个数组以容纳所有字符
- 然后只打印非零的
有很多方法可以做到这一点。其中一种方法是使用
\X
作为正则表达式,由捕获的匹配器组指定和分组
演示:
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.regex.MatchResult;
import java.util.regex.Pattern;
import java.util.stream.Collectors;
import java.util.stream.Stream;
public class Main {
public static void main(String[] args) {
// Test
Stream.of(
"giraffe",
"HeThe problem
The real cause of your problem is that there isn’t any CharStream
class. For this reason s.chars()
gives you an IntStream
. For this reason in turn in map(c -> count(s, c))
, c
has type int
. So you are trying to pass an int
to your count
method where it expects a char
. This gives you your error message. An int
can be converted to a char
, but some bits will be discarded, which is why the conversion is necessarily lossy.
The two obvious solutions
Solution 1: Tell Java that you mean to make this lossy conversion. Since you know that c
comes from a char
from your string, converting it back to a char
again won’t do any harm.
int[] occurences = s.chars().map(c -> count(s, (char) c)).toArray();
import java.util.LinkedHashMap;
导入java.util.Map;
导入java.util.regex.MatchResult;
导入java.util.regex.Pattern;
导入java.util.stream.collector;
导入java.util.stream.stream;
公共班机{
公共静态void main(字符串[]args){
//试验
溪流(
“长颈鹿”,
“问题是什么
问题的真正原因是没有任何CharStream
类。因此s.chars()
为您提供了一个IntStream
。因此,依次在map(c->count(s,c))中
,c
的类型为int
。因此,您试图将int
传递给count
方法,该方法需要char
。这会给您错误消息。int
可以转换为char
,但会丢弃一些位,这就是转换必然有损的原因
两个显而易见的解决方案
解决方案1:告诉Java您打算进行这种有损转换。因为您知道c
来自字符串中的char
,所以再次将其转换回char
不会造成任何伤害
public int count(String text, int ch) {
解决方案2:
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.regex.MatchResult;
import java.util.regex.Pattern;
import java.util.stream.Collectors;
import java.util.stream.Stream;
public class Main {
public static void main(String[] args) {
// Test
Stream.of(
"giraffe",
"HeThe problem
The real cause of your problem is that there isn’t any CharStream
class. For this reason s.chars()
gives you an IntStream
. For this reason in turn in map(c -> count(s, c))
, c
has type int
. So you are trying to pass an int
to your count
method where it expects a char
. This gives you your error message. An int
can be converted to a char
, but some bits will be discarded, which is why the conversion is necessarily lossy.
The two obvious solutions
Solution 1: Tell Java that you mean to make this lossy conversion. Since you know that c
comes from a char
from your string, converting it back to a char
again won’t do any harm.
int[] occurences = s.chars().map(c -> count(s, (char) c)).toArray();
您可以声明您的方法以接受int
:
public static Map<Character, Integer> histogram(String str) {
Map<Character, Integer> map = new TreeMap<>();
for (int i = 0; i < str.length(); i++) {
char ch = Character.toLowerCase(str.charAt(i));
map.put(ch, map.getOrDefault(ch, 0) + 1);
}
return map;
}
现在不需要转换(cast)。比较c==ch
仍然可以正常工作。它无论如何都在比较两个int
s,因此不会造成任何伤害
PS在其他答案中还有其他很好的解决方案和改进。就我个人而言,我会尝试将字符串预处理为计数映射,这样我就不必为每个字母再次计数。这不是必需的,您的代码只需进行上述两个更改中的一个即可正常工作。对不起,但我认为流
不适合这样做。简单的方法是使用Map
:
公共静态地图直方图(字符串str){
Map Map=newtreemap();
对于(int i=0;i
非常棒的详细答案。谢谢,我没有意识到问题是由于c
被转换为int
public int count(String text, int ch) {
public static Map<Character, Integer> histogram(String str) {
Map<Character, Integer> map = new TreeMap<>();
for (int i = 0; i < str.length(); i++) {
char ch = Character.toLowerCase(str.charAt(i));
map.put(ch, map.getOrDefault(ch, 0) + 1);
}
return map;
}