Reputation: 534
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
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
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
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