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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-11 05:54:43  来源:igfitidea点击:

Java 8 Streams: IntStream to String

javajava-8java-stream

提问by yyoon

In Java 8 streams API, calling chars()on any Stringobject returns an IntStreamobject containing all the characters.

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

What would be the correct way to convert the returned IntStreamobject back to a String? Calling toArray()would give me an int[], which is not accepted by any of the Stringconstructor.

将返回的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 Collectoras 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 appendCodePointmethod would do the trick as well,

usingStringBuilderappendCodePoint方法也可以解决问题,

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

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

System.out.println(intStreamToString);