Java 8 Streams:IntStream到String

yyo*_*oon 24 java java-8 java-stream

在Java 8流API中,调用chars()任何String对象都会返回IntStream包含所有字符的对象.

将返回的IntStream对象转换回String?的正确方法是什么?调用toArray()会给我一个int[],任何String构造函数都不接受.

Suf*_*ori 19

使用StringBuilderappendCodePoint方法也可以做到,

IntStream in = "Convert me to a String".codePoints();

String intStreamToString = in.collect(StringBuilder::new,
        StringBuilder::appendCodePoint, StringBuilder::append)
        .toString();

System.out.println(intStreamToString);
Run Code Online (Sandbox Code Playgroud)


Jon*_*eet 16

你可以使用toArray(),然后使用String(int[], int, int)构造函数.这并不完全令人满意,因为chars()指定返回UTF-16代码单元,基本上:

返回int的流,从此序列中对char值进行零扩展.任何映射到代理代码点的char都会被解释.

使用codePoints()反而会更加保持与此构造,其预计的代码点,而不是UTF-16代码单元.否则(with chars)如果您的原始字符串确实包含代理项对,您可能会发现您收到错误 - 我没有尝试过,但它会有意义.

我不知道一个简单的方法,不先转换为数组.


Edw*_*rzo 8

我很确定必须有很多方法可以做到这一点,但另一种方法是使用StringWriter:

IntStream in = "It was the best of times".chars();
StringWriter sw = new StringWriter();
in.forEach(sw::write); 
System.out.println(sw.toString());
Run Code Online (Sandbox Code Playgroud)

这一切也可以在收集器中表达为:

IntStream in = "It was the best of times".chars();
String text = in.collect(
    StringWriter::new, 
    StringWriter::write, 
    (swl, swr) -> swl.write(swr.toString())).toString();
System.out.println(text);
Run Code Online (Sandbox Code Playgroud)

  • @nullstein它也可以写成收藏家,正如我的版本所示,尽管我怀疑这使它更容易阅读.从好的方面来看,它确实具有更好的参考透明度,因为副作用对于流用户是隐藏的.但这最终类似于StringBuilder的答案. (2认同)

rmu*_*ler 5

这是另一个想法:

@Test
public void testIntStreamSequential() {
    final String testString = "testmesoftly";
    IntStream is = testString.chars();
    String result = is.collect(
        StringBuilder::new,
        (sb, i) -> sb.append((char)i),
        StringBuilder::append
        ).toString();
    assertEquals(testString, result);
}

@Test
public void testIntStreamParallel() {
    final String testString = "testmesoftly";
    IntStream is = testString.chars();
    String result = is.parallel().collect(
        StringBuilder::new,
        (sb, i) -> sb.append((char)i),
        StringBuilder::append
        ).toString();
    assertEquals(testString, result);
}
Run Code Online (Sandbox Code Playgroud)

请注意,使用Collector@Lii提出的专用效率不是很高,因为拳击所以你应该使用这三个参数构造(感谢@holger)