1. ホーム
  2. java

StringをStream of Stringsに分割するには?

2023-08-24 10:22:56

質問

にはどのようなものがありますか? ベスト String を Stream に分割する方法は何ですか?

私はこれらのバリエーションを見ました。

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

}

どのように解決するのですか?

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

という形式のメソッド参照のプロパティです。 expression::name で説明されているように、機能インターフェースのインスタンスを作成するときに式を評価し、その結果を取り込みます。 System.out::println に相当するラムダ式は何ですか? java.lang.NullPointerException がメソッド参照を使用してスローされますが、ラムダ式はスローされません。