将字符串转换为 java.util.Stream<Character>

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

有时我想对字符串中的每个字符做一些简单的事情。不幸的是,因为字符串是不可变的,所以除了循环遍历字符串之外没有好的方法,这可能会非常冗长。如果您改用 Stream,则可以做得更短,只需一两行。

有没有办法将 String 转换为 Stream<Character>

您可以使用 chars 方法,其中 return 是 IntStream 并将其映射到 char 您将得到 Stream<Character>mapToObj returns Object 在我们的例子 StreamCharacter 的值是 Stream,因为我们已经将 int 映射到 char 和 java 自动装箱Character 内部.

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

此外,在番石榴 (com.google.common.collect.Lists) 的帮助下,您可以像这样使用它,String Character 的 return 不可变列表。

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

您可以使用 CharSequence 中提供的 chars() 方法,并且由于 String class 实现了此接口,您可以访问它。 chars() 方法 returns 和 IntStream ,因此如果您想将 IntStream 转换为 Stream<Character>[=,则需要将其转换为 (char) 19=]

例如

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);
    }
}

通常使用 IntStream:

代码点流更安全
IntStream codePoints = string.codePoints();

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

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

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

更有效

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

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

虽然这种方法看起来不太实用,但如果您已经有一个 StringBuilder 或者想稍后将更多内容连接到同一个字符串,它可能会更有效。