Java 8 Streams:IntStream 到 String
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/28280721/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Java 8 Streams: IntStream to String
提问by yyoon
In Java 8 streams API, calling chars()
on any String
object returns an IntStream
object containing all the characters.
在 Java 8 流 API 中,调用chars()
任何String
对象都会返回一个IntStream
包含所有字符的对象。
What would be the correct way to convert the returned IntStream
object back to a String
? Calling toArray()
would give me an int[]
, which is not accepted by any of the String
constructor.
将返回的IntStream
对象转换回 a的正确方法是String
什么?调用toArray()
会给我一个int[]
,它不被任何String
构造函数接受。
采纳答案by Jon Skeet
You can use toArray()
, then the String(int[], int, int)
constructor. This isn't entirely satisfactory as chars()
is specified to return UTF-16 code units, basically:
您可以使用toArray()
, 然后是String(int[], int, int)
构造函数。这并不完全令人满意,因为chars()
指定返回 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.
返回一个 int 流,零扩展此序列中的 char 值。映射到代理代码点的任何字符都未经解释地传递。
Using codePoints()
instead would be more in-keeping with this constructor, which expects code points rather than UTF-16 code units. Otherwise (with chars
) if your original string doescontain surrogate pairs, you may find you get an error - I haven't tried it, but it would make sense.
使用它codePoints()
会更符合这个构造函数,它需要代码点而不是 UTF-16 代码单元。否则 (with chars
) 如果您的原始字符串确实包含代理对,您可能会发现您收到错误 - 我没有尝试过,但它会有意义。
I don't know of a simple way of doing this without converting to an array first.
我不知道不先转换为数组的简单方法。
回答by rmuller
This is an other idea:
这是另一个想法:
@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);
}
Note that using a dedicated Collector
as proposed by @Lii is not very efficient, because of the boxing so you should use this three argument construct (thanks @holger)
请注意,使用Collector
@Lii 建议的专用不是很有效,因为装箱所以你应该使用这三个参数构造(感谢@holger)
回答by Edwin Dalorzo
I am pretty sure there must be many ways to do it, but another way is by using a StringWriter
:
我很确定一定有很多方法可以做到这一点,但另一种方法是使用StringWriter
:
IntStream in = "It was the best of times".chars();
StringWriter sw = new StringWriter();
in.forEach(sw::write);
System.out.println(sw.toString());
This all could also be expressed in a collector as:
这一切也可以在收集器中表示为:
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);
回答by Sufiyan Ghori
using StringBuilder
's appendCodePoint
method would do the trick as well,
usingStringBuilder
的appendCodePoint
方法也可以解决问题,
IntStream in = "Convert me to a String".codePoints();
String intStreamToString = in.collect(StringBuilder::new,
StringBuilder::appendCodePoint, StringBuilder::append)
.toString();
System.out.println(intStreamToString);