如何在Java 8中将字符流转换为字符串

21

如何在Java 8中将Stream<Character>转换为String?由于Collectors.joining()期望的是CharSequence,因此会出现编译错误。


3
请查看以下链接以获取更多信息:https://dev59.com/UGIj5IYBdhLWcg3wb0rX - jub0bs
3
我不太确定为什么这个问题被关闭了。它提出了一个单一的问题(如何将Stream<Character>转换为String),并且还说明了为什么一个看似显而易见的解决方案行不通。这个问题应该如何更加专注? - raner
2个回答

35

请参考@jubobs的解决方案链接。也就是说,在您的情况下,可以这样做:

Stream<Character> testStream = Stream.of('a', 'b', 'c');

String result = testStream.collect(Collector.of(
    StringBuilder::new,
    StringBuilder::append,
    StringBuilder::append,
    StringBuilder::toString));

使用StringBuilder#append(char c)比先将每个字符映射到String,然后再进行joining更加高效,因为它能够避免中间步骤。


5
不适用于"abc".chars(),因为它是一个IntStream。在这种情况下,需要使用.collect(StringBuilder::new, StringBuilder::appendCodePoint, StringBuilder::append)。请参见https://dev59.com/UGIj5IYBdhLWcg3wb0rX#20268845。 - koppor
1
据我所知,第一个 StringBuilder::append 的引用调用的是 StringBuilder.append(Object),这会在每个字符上调用 toString(),从而影响性能。为了确保调用正确的 append 方法,请使用以下代码:.collect(StringBuilder::new, (builder, c) -> builder.append((char) c), StringBuilder::append) - Ben Romberg
此 collect 方法不适用于 IntStream,但适用于 Stream。你可以使用 .boxed() 方法进行转换。 - Mauricio Rodriguez
我简直不敢相信这现在还不是标准API的一部分。 - Valerij Dobler
Performant这个词的实际意思是什么?我在词典里找不到这个词。 :) - undefined

14
Character 转换为 String
Stream<Character> st = Stream.of('C','h','t');
String result = st.map(c->c.toString()).collect(Collectors.joining());
System.out.println(result);  //Cht

或者通过使用方法引用

st.map(Object::toString).collect(Collectors.joining())

Collectors.joining 内部使用 StringBuilder,可以在这里查看。

或者只需使用 forEach

StringBuilder builder = new StringBuilder();

    Stream<Character> st = Stream.of('C','h','t');

    st.forEach(ch->builder.append(ch));

或者使用.map(Character::toString),但这比StringBuilder::append不够有效。 - Eugene
...map(Object::toString).... 应该可以工作。 - user85421
3
Collectors.joining 内部使用 StringBuilder,但这并不改变使用 StringBuilder.append(char) 直接追加 Character 元素比先将它们转换成 String 再使用 StringBuilder.append(String) 更有效率的事实。但由于这些都是长度为一的字符串,每个元素的成本并不会很高。 - Holger

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