使用Java 8流计算字符串数组的长度总和

8

我写了这段代码,但它无法编译:

String[] text = {"hello", "bye"};
IntStream.of(Arrays.stream(text).map(String::length)).sum()

我需要将流转换为IntStream吗?为什么我将String::length传递给map()函数时会出现错误?


尝试使用 .map(String::length).reduce(0,(m1,m2)->m1+m2); - Hadi J
1
String.join("", text).length() 怎么样?虽然效率不高,但更加简洁。 - shmosel
@HadiJ 取决于期望的结果是什么。 - shmosel
3个回答

14

为了获得一个IntStream实例,您应该使用Stream.mapToInt

String[] text = {"hello", "bye"};
int total = Arrays.stream(text).mapToInt(String::length).sum();

如果您将它们全部连接在一起,然后执行.length会怎样? - Eugene
@Eugene 是的,那也可以。但是这样会重复使用内存。如果有很多字符串,也许这种方式更好。 - fps
4
@Eugene 说实话,与其优化速度或内存使用,我认为创建一个新的 String 实例并不完全正确,当您只想获得总长度时。拼接所有字符串以找出最终长度就像结婚几次来检查您的婆婆是否是个好女人一样。你最好在向你的女友求婚之前了解一下你未来的婆婆…… - fps
1
抱歉我没有详细说明。我认为编辑有误导性,因为原帖使用了 map(String::length),而你强调使用 mapToInt() 作为解决方案。这给人一种感觉,好像这是问题所在,但实际上它只是一种优化。对不起,这不是编辑的问题,而是在原始答案中也存在。 - davidxxx
1
如果你想要一个真正不同的选择,你可以考虑使用 Arrays.stream(text).flatMapToInt(String::chars).count(),但是只要计算所有字符(char 即 UTF-16 单元),你的解决方案就是最好的。当计算代码点 (Arrays.stream(text).flatMapToInt(String::codePoints).count()) 或实际字符时(是否有实际的解决方案?)会变得更加有趣... - Holger
显示剩余4条评论

3

试一试

Arrays.stream(text)
      .filter(Objects::nonNull)
      .mapToInt(String::length)
      .reduce(0,Integer::sum);

1
当然您想使用一个方法引用 0,Integer::sum,但那只是 @davidxxx 的精确复制品,而 @Federico 的 sum 方法则在内部完成了同样的工作。 - Eugene
所有得分高于125的人都可以进行负分投票,但建议您写下原因。 - Hadi J
@Eugene 121 在6,244上。确实你从未这样做过。愿上帝保佑你 :) - davidxxx
2
@Hadi J 我也被踩了。这就是游戏规则。好的答案通常会被点赞,而不太好的答案有时会被踩。 - davidxxx
我也没有投反对票。只有在答案明显错误的情况下才会投反对票,而这并不是这种情况。此外,您正在检查“null”,这是绝对正确的。 - fps
1
我没有给你的回答点踩,但是它有一些缺陷。.map(String::length) 返回一个 Integer,而你在 reduce() 中对它们求和,这会导致每个 Integer 都要进行拆箱操作。此外,使用方法引用来求和 int 更易读。 - davidxxx

1

我需要将流转换为IntStream吗?

嗯,你不必为了找到所有字符串的总长度而这样做,但出于性能原因最好这样做。

为什么当我将String::length传递给map()函数时会出错?

如果你将方法引用更改为lambda表达式,你会得到一个更好的提示,即:

 IntStream.of(Arrays.stream(text).map(e -> e.length())).sum();

现在,您不仅在map函数附近有一个波浪线,还在IntStream.of方法下方也有一个波浪线。在IDE上悬停在of方法上后,我收到消息:

"cannot resolve method of(java.util.stream.Stream<R>)"

现在,这告诉我们我们正在向of方法传递错误的参数。 of方法有两个重载版本:

of(int... values)

of(int t)

正如您所看到的,这两种方法都需要传递一组值或单个值,类型为int
显然,在这种情况下,IntStream.of方法不是我们的朋友,而我们将需要:
int length = Arrays.stream(text) // Stream<String>
                   .mapToInt(String::length)  //IntStream
                   .sum(); // int

这种方法只是将每个字符串映射到其长度,并将它们全部相加。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接