我试着用Java中的Streams计算单词。这就是我的尝试:
public static int countWords(String s) {
return s.chars().reduce((x, y) -> {
if((char)y == ' ')
++x;
return x;
}).orElse(0);
}
但countWords("asd")
返回97.为什么?我认为chars
会返回IntStream
,其实际上由char
组成。所以,我只是把它投到char
。怎么了?
答案 0 :(得分:8)
虽然你的问题是指计算单词,但你的代码似乎是为了计算空格而设计的。如果这是你的意图那么我会建议:
=match($A:$A, indirect("Sheet 2!A:E"),0)
这样可以避免代码中出现的许多投射错误,如果对您的域名更有意义,可以将其更改为input.chars().filter(Character::isSpaceChar).count();
。
但是,如果您希望计算单词,那么最简单的解决方案就是在空格上isWhitespace
,然后计算非空单词:
split
答案 1 :(得分:7)
reduce运算符有不同的重载:
如果未指定“x”的标识值,则reduce运算符将从流中获取第一个值。因此'x'最后是字母'a',整数,即97.您可能想要将代码更改为:
public static int countWords(String s) {
return s.chars().reduce(0, (x, y) -> {
if((char)y == ' ')
return x + 1;
return x;
});
}
答案 2 :(得分:7)
我建议采用更多功能性方法:
public static long countWords(String s) {
return Arrays
.stream(s.split(" "))
.filter(w -> !w.isEmpty())
.count();
}
答案 3 :(得分:2)
使用reduce时,你正在处理元组:x
是第一个字符或累加器,y
是secone char变量。
此处,x
始终指向a
,其中ASCII值为97
Pattern#splitAsStream(CharSequence)
您可能希望在您的情况下使用此方法,它可以正确完成工作,并且您可以编写更易于维护的代码。
public static int countWords(String s) {
return (int)Pattern.compile(" ")
.splitAsStream(s)
.count();
}
答案 4 :(得分:1)
计算空间:查看短跑运动员的反应;表现:看到对erkfel的回应的评论;正确应用reduce:请参阅Andrew Williamson的回复。
现在我将它们全部合并到以下内容中:
public static int countWords(String s)
{
int c = s.chars().reduce(0, (x, y) ->
{
if(x < 0)
{
if(Character.isWhitespace(y))
{
x = -x;
}
}
else
{
if(!Character.isWhitespace(y))
{
x = -(x + 1);
}
}
return x;
});
return c < 0 ? -c : c;
}
这以非常有效的方式计算真实的单词,而不是空白。内部隐藏着一个小技巧:我使用负值来表示“在一个单词中”的状态,使用正值来表示“在空白序列中”。我选择它不需要携带额外的布尔值,从而使我们免于编写实现IntBinaryOperation的显式类(另外,这使得lamda表达式保持无状态,仍然在reduction文章中讨论的并行化是不可能的此运算符不关联...))。
编辑:正如霍尔格指出的那样(我认为是正确的),这种用法是滥用实际上的实际意图(有几个相似的值,并将它们减少到一个仍然与原始值相同;示例:汇总或乘以数值列表,结果仍为数字 - 或连接字符串列表,结果仍为字符串)。
所以简单地迭代字符串似乎更合适:
public static int countWords(String s)
{
int count = 0;
boolean isWord = false;
for(int i = 0; i < s.length(); i++)
{
if(isWord)
{
if(Character.isWhitespace(s.charAt(i)))
{
isWord = false;
}
}
else
{
if(!Character.isWhitespace(s.charAt(i)))
{
++count;
isWord = true;
}
}
return count;
}
我个人喜欢紧凑型变体,虽然不太容易理解:
public static int countWords(String s)
{
int count = 0;
boolean isWord = false;
for(int i = 0; i < s.length(); i++)
{
boolean isChange = isWord == Character.isWhitespace(s.charAt(i));
isWord ^= isChange;
count += isWord & isChange ? 1 : 0;
}
return count;
}
答案 5 :(得分:1)
流?怎么样:
int wordCount = str.trim().split("\\s+").length();
如果你拼命必须使用溪流(不推荐):
int wordCount = Arrays.stream(str.trim().split("\\s+")).count();