Mein Professor sagte, sie seien völlig verschieden, aber ich lese, dass sie sich ziemlich ähnlich sind. Ich weiß nicht, welchen Kontext "anders" er meinte. Und wenn diese Frage bereits beantwortet wurde, verlinke sie einfach. Vielen Dank.Kann jemand den Unterschied zwischen einer tiefen Kopie und einer defensiven Kopie erklären?
Antwort
Tiefe Kopie: eine Art von Objektkopiertechniken: alle Daten in der Struktur tief kopieren. Eine "harte" Methode, um eine tiefe Kopie eines Objekts zu erzeugen, besteht darin, sie zu serialisieren und dann zu entserialisieren. Für Bäume ist rekursives Kopieren im Allgemeinen eine effiziente Lösung.
Defensive Kopie: Ergebnis einer Operation zum Schutz interner Daten. Normalerweise ist es eine tiefe oder flache Kopie, die verwendet wird, um einen unerwünschten Zugriff durch ein internes Referenzergebnis zu verhindern.
public int[] getValues() {
return Arrays.copyOf(values, values.length);
}
In der Regel sollten Sie defensive Kopie verwenden, um eine innere Anordnung, Sammlung oder eine andere Struktur zu schützen. Wenn wir einfach mit (einem Verweis auf) dem Array zurückkommen, könnte der Benutzer unsere interne Struktur ändern!
Siehe ein Beispiel.
Tom schreibt eine Klasse, die gemächlich einige Aggregationen einer Integer
Sammlung Caches:
public class CachedIntegerAggregator {
private List<Integer> integers;
private boolean isSumCalculated = false;
private int sum = 0;
private boolean isMultiCalculated = false;
private int multi = 0;
public CachedIntegerAggregator(Integer... integers) {
this(Arrays.asList(integers));
}
public CachedIntegerAggregator(Collection<Integer> integers) {
this.integers = new ArrayList<Integer>(integers);
}
public List<Integer> getIntegers() {
return integers;
}
public int getSum() {
if (!isSumCalculated) {
sum = 0;
for (Integer integer: integers) {
sum += integer;
}
isSumCalculated = true;
}
return sum;
}
public int getMulti() {
if (!isMultiCalculated) {
multi = 1;
for (Integer integer: integers) {
multi *= integer;
}
isMultiCalculated = true;
}
return multi;
}
}
Jerry verwendet die oben Klasse auf diese Weise:
CachedIntegerAggregator aggregator = new CachedIntegerAggregator(2, 3, 4);
// hm, what is the sum?
System.out.println(aggregator.getSum());
// let's print of integers
List<Integer> integers = aggregator.getIntegers();
System.out.println(integers);
// now, see the double
int size = integers.size();
for (int i = 0; i < size; i++) { // (oops! this changes internal data!)
integers.set(i, integers.get(i) * 2);
}
System.out.println(integers);
// hm, see sum and multi
System.out.println(aggregator.getSum());
System.out.println(aggregator.getMulti()); // (oops! total inconsistency!)
Ausgang:
9
[2, 3, 4]
[4, 6, 8]
9
192
Was ist das Hauptproblem? Tom verliert eine veränderliche innere Struktur. Was ist die Lösung? In getIntegers()
eine Kopie davon vor der Rückkehr machen:
public List<Integer> getIntegers() {
return new ArrayList<Integer>(integers);
}
In einigen Fällen whould ein unveränderliches Wrapper auch richtig sein:
public List<Integer> getIntegers() {
return Collections.unmodifiableList(integers);
}
Leistung? Im Allgemeinen, mach dir keine Sorgen darüber. Die schnelle Objekterstellung ist einer der wichtigsten Java-Vorteile. Natürlich gibt es komplexe Strukturen, die ineffizient kopiert werden. In diesem Fall können Sie die Copy-on-Write-Technik verwenden. Einige große Datenstrukturimplementierungen verfügen über eine Unterstützung für Copy-on-Write, z. B. BigList.
Defensive Kopien müssen keine tiefen Kopien sein. Sagen wir, ich habe ein 'Klasse Foo {privates Widget [] Widgets; ...} 'wo' Widget' veränderbar ist und ich eine Methode habe, die meine 'Widgets' zurückgibt. Ich kann das Array flach kopieren, um zu verhindern, dass die Außenwelt die internen Details meines "Foo" verändert, aber ich muss nicht jedes "Widget" kopieren, damit es eine defensive Kopie ist. – Radiodef
Korrekt. Ich habe den Text geändert. –
@Radiodef Ich verstehe nicht, wie eine defensive Kopie eine flache Kopie sein kann? Wenn Sie eine flache Kopie verwenden, kann der Empfänger das Innere des Objekts ändern, das keine defensive Kopie ist. – Nier
- 1. Was ist der Unterschied zwischen einer flachen Kopie und einer tiefen Kopie mit JavaScript-Arrays?
- 2. Schreiben einer tiefen Kopie - Kopieren eines Zeigerwerts
- 3. Kann jemand den Unterschied zwischen Schließungs- und anonymen Funktionen erklären?
- 4. Kann jemand den Unterschied zwischen Ajax und Ruhe erklären?
- 5. Erstellen einer Kopie einer Ansicht?
- 6. Könnte jemand bitte den Unterschied zwischen einer "Referenz" und einem "Zeiger" in diesem Fall erklären?
- 7. Wie die Arbeitskopie, Staging Kopie und engagierte Kopie einer Datei mit Git
- 8. Flache Kopie und tiefe Kopie in C
- 9. Generische Methode zum Erstellen einer tiefen Kopie aller Elemente in einer Sammlung
- 10. Unterschiede zwischen [NSArray arrayWithArray:] und [NSArray Kopie]
- 11. Erstellen einer Kopie einer UIView in Swift
- 12. Erstellen einer statischen Kopie einer MoinMoin-Site
- 13. Gibt es einen Unterschied zwischen der ** Kopie ** und ** addAll **?
- 14. PHP: Erstellen einer Kopie einer Referenzvariablen
- 15. Gibt es einen Unterschied zwischen einer SVN-Kopie und einem SVN-Zweig?
- 16. Kann jemand den Unterschied zwischen GCM und Google Pub/Sub
- 17. Was ist der Unterschied zwischen SVN-Kopie und Svn-Merge zum Erstellen einer Verzweigung?
- 18. Kann jemand den Unterschied zwischen "Version" und "Update-Versionen" im Internet Explorer erklären?
- 19. Kann jemand den Unterschied zwischen diesen beiden HTTP-Anrufen erklären und warum einer nicht funktioniert, aber der andere nicht?
- 20. Kopie vs starke Eigenschaften
- 21. T4 Kopie Enum zwischen Projekten
- 22. Kann jemand OAuth erklären?
- 23. vi Suche Kopie Paste Suche Kopie
- 24. Speichern einer Kopie des aktuellen Objekts
- 25. svn Kopie auf einer Teilmenge eines Verzeichnisses
- 26. Kopie Werte zwischen Variablen in Bash-Skript
- 27. nUnit - ignoriere GAC-Kopie einer DLL
- 28. Bearbeitung in einer Kopie von Arraylist Original
- 29. Speichern einer Offline-Kopie der Datenbank
- 30. C#: Optimieren einer großen Array-Kopie
Nur der Zweck. Eine tiefe Kopie bedeutet, dass Sie jedes Element kopieren (ohne Angabe des Grundes), und eine defensive Kopie bedeutet, dass Sie kopieren, um zu verhindern, dass jemand anders auf dasselbe Objekt zugreift (z. B. zur Thread-Sicherheit). – markspace
Ich kann in einem Toyota zur Arbeit fahren, aber zur Arbeit fahren ist völlig anders als ein Toyota. Einer ist eine Art von Auto, einer ist eine Art, wie ein Auto benutzt wird. Eine tiefe Kopie ist eine Art von Kopie und eine defensive Kopie ist eine Art, wie eine Kopie verwendet wird. – Radiodef