これは次のようにJavaの9ソリューションは、最も可能性の高いどのように見えるかです。 flatMap
を介してストリームのストリームと一致のストリームを組み合わせることで、ファイルのすべての一致を処理することができます。元のコードは最初の行の一致を処理するだけなので、同じ行為を得るために各行の一致にlimit(1)
を追加するだけです。
残念ながら、この機能は、Java 8に欠けている、しかし、今後のリリースに潜入すると、暫定的な解決策は、のように見えるかもしれどのようなアイデア取得できます:サブストリームの作成を簡素化するために
Matcher m = Pattern.compile("name: '(.+)'").matcher("");
try(Stream<String> lines = Files.lines(ruleFile)) {
lines.flatMap(line -> m.reset(line).find()? Stream.of(m.toMatchResult()): null)
.forEach(mr -> System.out.println(mr.group(1)));
}
を、このソリューションが利用最初の一致のみが意図され、最初に単一の要素ストリームが作成されることを意味します。
しかし、問題のパターン'name: '(.+)'
と、我々が.+
としてマッチの数を制限するかどうかは関係ありませんのでご注意を貪欲に、最後のフォローアップ'
ラインのまでのすべての文字にマッチしますので、他の試合は不可能です。むしろ最後 1またはname: '([^']*)'
と同じように、明示的に'
をスキップして威嚇するより次'
まで消費name: '(.*?)'
とのような消極的量指定子を使用している場合物事は異なっています。シングルスレッドの使用(これはこれまで、並列処理の恩恵を受けるにくい)でうまく動作用いる上記
ソリューション共有Matcher
。あなたがスレッドセーフ側になりたい場合しかし、あなただけPattern
を共有することができ、代わりにm.reset(line)
を呼び出すMatcher
を作成します。
Pattern pattern = Pattern.compile("name: '(.*)'");
try(Stream<String> lines = Files.lines(ruleFile)) {
lines.flatMap(line -> pattern.matcher(line).results().limit(1))
.forEach(mr -> System.out.println(mr.group(1)));
}
RESPを。 Javaの場合8
try(Stream<String> lines = Files.lines(ruleFile)) {
lines.flatMap(line -> {Matcher m=pattern.matcher(line);
return m.find()? Stream.of(m.toMatchResult()): null;})
.forEach(mr -> System.out.println(mr.group(1)));
}
これは、ローカル変数の導入によって簡潔ではありません。これは、前map
操作することで回避できますが、私たちがいる限り、この時点であるときに、ラインごとに単一の試合のために、我々は唯一のヘッドとして、我々はflatMap
その後、必要はありません。各Matcher
ので
try(Stream<String> lines = Files.lines(ruleFile)) {
lines.map(pattern::matcher).filter(Matcher::find)
.forEach(m -> System.out.println(m.group(1)));
}
を一度だけ使用され、非干渉的な方法で、その変更可能な性質はここで害されず、不変のMatchResult
への変換は不要になる。することができ
それが今まで必要になった場合ただし、これらのソリューションは、行ごとに複数の一致を処理するためにスケーリングすることができない...
'map(p :: matcher)'パイプラインステージは、読み込まれた各行に対して新しい 'Matcher'オブジェクトを作成します。非常に大きなファイルの場合、これは効率の悪いソースになります。代わりに、再利用可能な 'Matcher'オブジェクトを作成することができます。' .map(matcher :: reset) 'は、ここで示すように、再利用可能な' matcher'に読み込まれた行からマップするために使用されます(https: /stackoverflow.com/a/47877960/3690024)。ストリームパイプラインでのステートフルオブジェクトの再利用はあらゆる種類のルールに違反しますので、大きなファイルを読んでいる場合のみこれを推奨し、ボトルネックと判断します。 – AJNeufeld