xenia
xenia

Reputation: 534

Convert a String to a java.util.Stream<Character>

Sometimes I want to do something simple with each character in a string. Unfortunately, because a string is immutable, there is no good way of doing it except looping through the string which can be quite verbose. If you would use a Stream instead, it could be done much shorter, in just a line or two.

Is there a way to convert a String into a Stream<Character>?

Upvotes: 10

Views: 7042

Answers (3)

Tagir Valeev
Tagir Valeev

Reputation: 100169

It's usually more safe to use stream of code points which is IntStream:

IntStream codePoints = string.codePoints();

This way Unicode surrogate pairs will be merged into single codepoint, so you will have correct results with any Unicode symbols. Example usage:

String result = string.codePoints().map(Character::toUpperCase)
        .collect(StringBuilder::new, StringBuilder::appendCodePoint, StringBuilder::append)
        .toString();

Also note that you avoid boxing, thus it might be even more effective than processing Stream<Character>.

Another way to collect such stream is to use separate StringBuilder:

StringBuilder sb = new StringBuilder();
String result = string.codePoints().map(Character::toUpperCase)
                      .forEachOrdered(sb::appendCodePoint);

While such approach looks less functional, it may be more efficient if you already have a StringBuilder or want to concatenate something more later to the same string.

Upvotes: 9

Akash Thakare
Akash Thakare

Reputation: 22972

You can use chars method which returns IntStream and by mapping it to char you will have Stream<Character>. mapToObj returns Object valued Stream in our case Stream of Character, because we have mapped the int to char and java Auto Boxed it to Character internally.

Stream<Character> stream = "abc".chars().mapToObj(c -> (char)c);

Moreover, with the help of guava (com.google.common.collect.Lists) you can use it like this, which return immutable list of Character from the String.

Stream<Character> stream = Lists.charactersOf("abc").stream();

Upvotes: 2

sol4me
sol4me

Reputation: 15698

You can use chars() method provided in CharSequence and since String class implements this interface you can access it. The chars() method returns an IntStream , so you need to cast it to (char) if you will like to convert IntStream to Stream<Character>

E.g.

public class Foo {

    public static void main(String[] args) {
        String x = "new";

        Stream<Character> characters = x.chars().mapToObj(i -> (char) i);
        characters.forEach(System.out::println);
    }
}

Upvotes: 10

Related Questions