Java 8 Streams:IntStream到String

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

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

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

返回int的流,从此序列中对char值进行零扩展。 映射到代理代码点的任何字符都是未解释的。

使用codePoints()代替将更加保持这个构造函数,它需要代码点而不是UTF-16代码单元。 否则(使用chars )如果您的原始字符串确实包含代理项对,您可能会发现错误 – 我没有尝试过,但它会有意义。

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

使用StringBuilderappendCodePoint方法也可以做到这一点,

 IntStream in = "Convert me to a String".codePoints(); String intStreamToString = in.collect(StringBuilder::new, StringBuilder::appendCodePoint, StringBuilder::append) .toString(); System.out.println(intStreamToString); 

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

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

这一切也可以在collections家中表达为:

 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); 

这是另一个想法:

 @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); } 

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