将String转换为java.util.Stream <Character>

Loo*_*vjo 8 java string java-8 java-stream

有时我想对字符串中的每个字符做一些简单的事情.不幸的是,因为字符串是不可变的,除了循环遍历字符串之外没有好的方法可以做到这一点,这可能非常冗长.如果你使用Stream代替它,它可以做得更短,只需要一两行.

有没有办法将a转换StringStream<Character>

sol*_*4me 8

您可以使用chars()提供的方法CharSequence,因为String类实现了此接口,您可以访问它.该chars()方法返回一个IntStream,因此(char)如果您想转换IntStream为,则需要将其强制转换为Stream<Character>

例如

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);
    }
}
Run Code Online (Sandbox Code Playgroud)


Tag*_*eev 5

使用代码点流通常更安全,它是IntStream:

IntStream codePoints = string.codePoints();
Run Code Online (Sandbox Code Playgroud)

这样,Unicode代理项对将合并为单个代码点,因此您可以使用任何Unicode符号获得正确的结果.用法示例:

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

另请注意,您可以避免装箱,因此它可能比处理更有效Stream<Character>.

收集此类流的另一种方法是单独使用StringBuilder:

StringBuilder sb = new StringBuilder();
String result = string.codePoints().map(Character::toUpperCase)
                      .forEachOrdered(sb::appendCodePoint);
Run Code Online (Sandbox Code Playgroud)

虽然这种方法看起来功能较少,但如果您已经拥有StringBuilder或希望稍后将某些内容连接到同一个字符串,则可能会更有效.