2017-01-18 2 views
1

Ich war ein Prädikat Objekt, mein erster Versuch klonen wollte:Klonen ein Prädikat

Predicate<String> p1 = str -> str.isEmpty(); 
Predicate<String> p2 = str -> p1.test(str); 

Aber in diesem Fall, wenn p1 Änderung, p2 Änderung zu. Gibt es eine Möglichkeit, ein Prädikat so zu klonen, dass sich p2 nicht ändert?

+3

Was wird hier geklont? Ihre Prädikate sind zustandslos, Sie sollten also kein Problem haben. – teppic

+0

Warum können Sie das alte nicht wiederverwenden? – Moira

+0

Eine andere Variable einführen. Wenn tou p1 endgültig ist und p3 = p1 einführt, können Sie p1 als unveränderbar und p3 als änderbares ref verwenden. –

Antwort

2

Das Problem, mit dem Sie konfrontiert werden, ist nicht, dass sich das Prädikat ändern wird, sondern dass eine der externen Variablen, auf die das Prädikat implizit verweist, sich ändern wird. Daher würde eine Kopie des Prädikats nicht helfen, da es bereits unveränderlich ist.

eine temporäre Variable zu machen p1 ‚s-Wert zu erfassen, soll dieses Problem beheben:

Predicate<String> p1 = str -> str.isEmpty(); 
final Predicate<String> pTemp = p1; 
Predicate<String> p2 = str -> pTemp.test(str); 

Der Grund für die Korrektur funktioniert, ist, dass, wenn Sie p1 neu zuweisen, das alte Prädikat-Objekt wird nicht verändert; Es wird durch eine komplett neue Prädikat-Instanz ersetzt. Das alte Prädikatobjekt existiert immer noch, aber in Ermangelung von Live-Referenzen wird es für die Garbage Collection geeignet.

Wenn Sie pTemp hinzufügen, wird das alte Prädikat aus zwei Variablen referenziert - nämlich p1 und . An diesem Punkt hat die Neuzuweisung p1 keine Auswirkung auf pTemp, so dass das Verhalten von p2 unverändert bleiben würde.

Ich denke, das wäre in einer Schleife nützlicher, wenn Sie ein Prädikat inkrementell erstellen.

+1

Danke, das funktioniert, obwohl ich verstehe, warum, kannst du erklären, was hinter der Szene passiert, bitte? – DBLouis

+0

Neben der Unbrauchbarkeit des Klonens an sich kann man einfach 'Prädikat p2 = p1 :: test;' verwenden, um 'p1' dauerhaft an das neue' Prädikat' zu binden. Dann haben nachfolgende Änderungen an "p1" keinen Einfluss auf "p2". Um zu illustrieren, warum das Klonen nutzlos ist, können Sie dasselbe erreichen, indem Sie einfach 'Prädikat p2 = p1;' verwenden, es klont nicht, aber hat den gleichen Effekt, die Prädikate, auf die 'p1' und' p2' verweisen Das gleiche Verhalten und die nachfolgenden Änderungen an 'p1' haben keinen Einfluss auf' p2' ... – Holger