web-dev-qa-db-ja.com

文字列を文字列のストリームに分割する方法は?

文字列をストリームに分割するbestメソッドとは何ですか?

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

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

}
45
slartidan

まあ、String.splitは配列を返すので、Arrays.streamは配列を介したストリーミングの標準的なイディオムとして常にお勧めします。 Stream.ofvarargsメソッドです。これはたまたま配列を受け入れるだけです。varargsメソッドは配列を介して実装され、varargsがJavaに導入されたときに互換性の問題があったためです。可変引数を受け入れるように改造された既存のメソッド。

Pattern.compile(",").splitAsStream(string)には、中間配列を作成するのではなく、直接ストリーミングするという利点があります。したがって、多数の部分文字列の場合、これにはパフォーマンス上の利点があります。一方、デリミタが単純な場合、つまり単一のリテラル文字の場合、String.split実装は、正規表現エンジンを使用する代わりに高速パスを通過します。したがって、この場合、答えは簡単ではありません。

ストリーミングが別のストリーム内で発生する場合、例えば.flatMap(Pattern.compile(pattern) ::splitAsStream)外部ストリームのすべての文字列ではなく、パターンを1回だけ分析する必要があるという利点があります。

59
Holger

(1)と(2)については、コードはほとんど同じなので、それほど違いはありません。
(3)については、メモリ(必ずしもCPUである必要はありません)の観点からははるかに効果的ですが、私の意見では、少し読みにくくなっています。

2
Alexey Soshin