Java 8 个流:IntStream 到 String
Java 8 Streams: IntStream to String
在 Java 8 个流 API 中,在任何 String
对象上调用 chars()
returns 包含所有字符的 IntStream
对象。
将返回的 IntStream
对象转换回 String
的正确方法是什么?调用 toArray()
会给我一个 int[]
,这不被任何 String
构造函数接受。
可以使用toArray()
,然后是String(int[], int, int)
构造函数。这并不完全令人满意,因为 chars()
被指定为 return UTF-16 代码单元,基本上:
Returns a stream of int zero-extending the char values from this sequence. Any char which maps to a surrogate code point is passed through uninterpreted.
改用 codePoints()
会更符合此构造函数,它需要代码点而不是 UTF-16 代码单元。否则(使用 chars
)如果您的原始字符串 确实 包含代理项对,您可能会发现出现错误 - 我没有尝试过,但它是有道理的。
我不知道有没有先转换为数组的简单方法。
这是另一个想法:
@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)
我很确定一定有很多方法可以做到,但另一种方法是使用 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);
使用 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);
在 Java 8 个流 API 中,在任何 String
对象上调用 chars()
returns 包含所有字符的 IntStream
对象。
将返回的 IntStream
对象转换回 String
的正确方法是什么?调用 toArray()
会给我一个 int[]
,这不被任何 String
构造函数接受。
可以使用toArray()
,然后是String(int[], int, int)
构造函数。这并不完全令人满意,因为 chars()
被指定为 return UTF-16 代码单元,基本上:
Returns a stream of int zero-extending the char values from this sequence. Any char which maps to a surrogate code point is passed through uninterpreted.
改用 codePoints()
会更符合此构造函数,它需要代码点而不是 UTF-16 代码单元。否则(使用 chars
)如果您的原始字符串 确实 包含代理项对,您可能会发现出现错误 - 我没有尝试过,但它是有道理的。
我不知道有没有先转换为数组的简单方法。
这是另一个想法:
@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)
我很确定一定有很多方法可以做到,但另一种方法是使用 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);
使用 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);