在Java 8流API中,在任何chars()
对象上调用String
会返回包含所有字符的IntStream
对象。
将返回的IntStream
对象转换回String
的正确方法是什么?调用toArray()
会给我一个int[]
,任何String
构造函数都不会接受。{/ p>
答案 0 :(得分:18)
使用StringBuilder
' appendCodePoint
方法也可以做到这一点,
IntStream in = "Convert me to a String".codePoints();
String intStreamToString = in.collect(StringBuilder::new,
StringBuilder::appendCodePoint, StringBuilder::append)
.toString();
System.out.println(intStreamToString);
答案 1 :(得分:14)
您可以使用toArray()
,然后使用String(int[], int, int)
构造函数。这并不完全令人满意,因为chars()
被指定为返回UTF-16代码单元,基本上是:
返回一个int流,对此序列中的char值进行零扩展。映射到代理代码点的任何char都会通过未解释的传递。
使用codePoints()
代替更好地保持这个构造函数,它需要代码点而不是UTF-16代码单元。否则(使用chars
)如果您的原始字符串 包含代理项对,您可能会发现错误 - 我没有尝试过,但它会有意义。
我不知道在没有先转换为数组的情况下执行此操作的简单方法。
答案 2 :(得分:8)
我很确定必须有很多方法可以做到这一点,但另一种方法是使用StringWriter
:
IntStream in = "It was the best of times".chars();
StringWriter sw = new StringWriter();
in.forEach(sw::write);
System.out.println(sw.toString());
这一切也可以在收藏家中表达为:
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);
答案 3 :(得分: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);
}
请注意,使用@Lii提出的专用Collector
效率不高,因为拳击所以你应该使用这三个参数构造(感谢@holger)