のクローニング、私の最初の試みでした:私は述語オブジェクトのクローンを作成したい述語
Predicate<String> p1 = str -> str.isEmpty();
Predicate<String> p2 = str -> p1.test(str);
しかし、その場合には、あまりにもP1の変更、P2の変更場合。 p2が変わらないように述語をクローンする方法はありますか?
のクローニング、私の最初の試みでした:私は述語オブジェクトのクローンを作成したい述語
Predicate<String> p1 = str -> str.isEmpty();
Predicate<String> p2 = str -> p1.test(str);
しかし、その場合には、あまりにもP1の変更、P2の変更場合。 p2が変わらないように述語をクローンする方法はありますか?
あなたが直面している問題は、述語が変更されることではなく、述語によって暗黙的に参照される外部変数の1つが変更されることです。したがって、述語のコピーを作ることは、すでに不変なので、助けにならないでしょう。この問題を解決する必要がありp1
の値をキャプチャするために一時変数を作る
:修正プログラムが動作します
Predicate<String> p1 = str -> str.isEmpty();
final Predicate<String> pTemp = p1;
Predicate<String> p2 = str -> pTemp.test(str);
理由は、あなたがたときにp1
を再度割り当てることで、古い述語オブジェクトは変更されません。完全に新しい述語インスタンスに置き換えられます。古い述語オブジェクトはまだ存在しますが、ライブ参照がない場合は、ガベージコレクションの対象となります。
pTemp
を追加すると、古い述語は2つの変数、つまりp1
とpTemp
から参照されます。この時点で、p1
を再割り当てすることはpTemp
には影響しないため、p2
の動作も同様に変更されません。
これは、述語を段階的に構築するときに、ループ内でこれがより便利であると考えています。
ありがとうございました、それはうまくいきますが、私は理由を理解していますが、シーンの後ろで何が起こっているのか説明できますか? – DBLouis
クローン自体の役に立たないことに加えて、 'Predicate
ここでは何が複製されていますか?述語はステートレスなので、問題はないはずです。 – teppic
古いものを再利用できないのはなぜですか? – Moira
別の変数を導入してください。 touがp1を最終的にしてp3 = p1を導入した場合は、p1を変更不可として、p3を変更可能なrefとして使用できます。 –