如何将字符串拆分为字符串流?

2022-08-31 12:24:07

将字符串拆分为流的最佳方法是什么?

我看到了这些变化:

  1. Arrays.stream("b,l,a".split(","))
  2. Stream.of("b,l,a".split(","))
  3. Pattern.compile(",").splitAsStream("b,l,a")

我的优先事项是:

  • 鲁棒性
  • 可读性
  • 性能

一个完整的、可编译的示例

import java.util.Arrays;
import java.util.regex.Pattern;
import java.util.stream.Stream;

public class HelloWorld {

    public static void main(String[] args) {
        stream1().forEach(System.out::println);
        stream2().forEach(System.out::println);
        stream3().forEach(System.out::println);
    }

    private static Stream<String> stream1() {
        return Arrays.stream("b,l,a".split(","));
    }

    private static Stream<String> stream2() {
        return Stream.of("b,l,a".split(","));
    }

    private static Stream<String> stream3() {
        return Pattern.compile(",").splitAsStream("b,l,a");
    }

}

答案 1

Arrays.stream/String.split

由于 String.split 返回一个数组,我总是建议将其作为通过数组进行流式传输的规范习语。String[]Arrays.stream

String input = "dog,cat,bird";
Stream<String> stream = Arrays.stream(input.split( "," ));
stream.forEach(System.out::println);

Stream.of/String.split

Stream.of是一个varargs方法,它碰巧接受一个数组,因为varargs方法是通过数组实现的,并且当varargs被引入Java并且现有方法被改造为接受变量参数时,存在兼容性问题。

Stream<String> stream = Stream.of(input.split(","));     // works, but is non-idiomatic
Stream<String> stream = Stream.of("dog", "cat", "bird"); // intended use case

Pattern.splitAsStream

Pattern.compile(“,”).splitAsStream(string) 具有直接流式传输而不是创建中间数组的优点。因此,对于大量的子字符串,这可以带来性能优势。另一方面,如果分隔符是微不足道的,即单个文字字符,则实现将通过快速路径而不是使用正则表达式引擎。因此,在这种情况下,答案并非微不足道。String.split

Stream<String> stream = Pattern.compile(",").splitAsStream(input);

如果流式传输发生在另一个流中,例如 有一个优点是,模式只需要分析一次,而不是对外部流的每个字符串进行分析。.flatMap(Pattern.compile(pattern) ::splitAsStream)

Stream<String> stream = Stream.of("a,b", "c,d,e", "f", "g,h,i,j")
    .flatMap(Pattern.compile(",")::splitAsStream);

这是形式的方法引用的一个属性,它将在创建函数接口的实例时计算表达式并捕获结果,如 System.out::p rintln 和 java.lang 的等效 lambda 表达式中所述。NullPointerException 是使用方法引用而不是 lambda 表达式引发的expression::name


答案 2

关于(1)和(2)应该没有太大的区别,因为你的代码几乎是一样的。
关于(3),就内存(不一定是CPU)而言,这将更有效,但在我看来,阅读起来有点困难。