13

If I am working with Java streams, and end up with an IntStream of code point numbers for Unicode characters, how can I render a CharSequence such as a String?

String output = "input_goes_here".codePoints(). ??? ;  

I have found a codePoints() method on several interfaces & classes that all generate an IntStream of code points. Yet I have not been able to find any constructor or factory method that accepts the same.

I am looking for the converse:

➥ How to instantiate a String or CharSequence or such from an IntStream of code points?

Basil Bourque
  • 303,325
  • 100
  • 852
  • 1,154
  • 2
    Tagged with Java-9, where the `codePoints` API was introduced in the JDK. – Naman Aug 02 '19 at 02:28
  • @Naman `codePoints()` was introduced in Java 8. Either way, at what point do we stop tagging new versions? Do generics questions need to be tagged with `java-5`? – shmosel Aug 02 '19 at 18:41
  • To clarify: Unicode code point support has been added over the years across versions. [`StringBuilder::appendCodePoint`](https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/lang/StringBuilder.html#appendCodePoint(int)) & `String::codePointAt` in Java 5, [`CharSequence::codePoints`](https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/lang/CharSequence.html#codePoints()) in Java 8, and `String:codePoints` in Java 9. I agree with shmosel that there comes a point when tagging with Java version is superfluous. So it seems here. A topic for http://meta.StackOverflow.com. – Basil Bourque Aug 02 '19 at 20:31
  • @shmosel Oh, I went in with the `String` specific implementation as [documented here](https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/lang/String.html#codePoints()) and tagged the question. Missed the fact the `CharSequence` already had it. Not sure what the community in general practices. I follow the aspect that I would edit a question with java version tag if it contains APIs specific to that version such that people reading the question are not surprised by the use of such APIs. Does it make sense to revert it now? I do agree, that the question wasn't specific to Java-9. – Naman Aug 03 '19 at 03:15

3 Answers3

14

Use IntStream::collect with a StringBuilder.

String output = 
    "input_goes_here"
    .codePoints()                            // Generates an `IntStream` of Unicode code points, one `Integer` for each character in the string.
    .collect(                                // Collect the results of processing each code point.
        StringBuilder::new,                  // Supplier<R> supplier
        StringBuilder::appendCodePoint,      // ObjIntConsumer<R> accumulator
        StringBuilder::append                // BiConsumer<R,​R> combiner
    )                                        
    .toString()
;

If you prefer the more general CharSequence interface over concrete String, simply drop the toString() at the end. The returned StringBuilder is a CharSequence.

IntStream codePointStream = "input_goes_here".codePoints ();
CharSequence output = codePointStream.collect ( StringBuilder :: new , StringBuilder :: appendCodePoint , StringBuilder :: append );
Basil Bourque
  • 303,325
  • 100
  • 852
  • 1,154
shmosel
  • 49,289
  • 6
  • 73
  • 138
5

or more direct to String by using an array passed to new String(…)

IntStream intStream = "input_goes_here".codePoints();

int[] arr;
String output = new String( (arr = intStream.toArray()), 0, arr.length );


and here's the original short solution without the superfluous IntStream intStream assignment:

int[] arr;
String output = new String( (arr = "input_goes_here".codePoints().toArray()), 0, arr.length );

Kaplan
  • 2,572
  • 13
  • 14
0

not to forget the Java IO library:
use IntStream::collect with a StringWriter

String output = 
    "input_goes_here".codePoints() // Generates an IntStream of Unicode code points,
                                   //  one Integer for each character in the string.
    .collect(                      // Collect the results of processing each code point.
        StringWriter::new,         // Supplier<R> supplier
        StringWriter::write,       // ObjIntConsumer<R> accumulator
        (w1, w2) -> w1.write(      // BiConsumer<R,R> combiner
            w2.toString() ) )
    .toString();
Kaplan
  • 2,572
  • 13
  • 14