2017-11-08 2 views
0

Im folgenden Beispiel besteht das HashSet BigSet aus SmallSet HashSets. Ich möchte SmallSet löschen, ohne BigSet zu löschen.Java: Aktualisieren von Hashsets von Hashsets

Stattdessen, wenn ich den clear() Befehl auf SmallSet ausführen, wird BigSet auch gelöscht. Warum passiert das? Und wie kann ich nur SmallSet löschen, während BigSet intakt bleibt?

Ich habe Druckanweisungen hinzugefügt, um zu veranschaulichen, was vor sich geht.

import java.util.HashSet; 
import java.util.Set; 
import java.util.Arrays; 

public class G{ 
    public static final HashSet<HashSet> BigSet = new HashSet <HashSet>(); 
    public static final HashSet<Set> SmallSet = new HashSet<Set>(); 

    public static Set<Integer> method() { 
     Set<Integer> n = new HashSet<Integer>(Arrays.asList(10, 20, 30)); 
     SmallSet.add(n); 
     BigSet.add(SmallSet); 
     System.out.println(SmallSet); 
     System.out.println(BigSet); 
     SmallSet.clear(); 
     System.out.println(SmallSet); 
     System.out.println(BigSet); 
     return n; 
    } 

    public static void main(String[] args) { 
     method(); 
    } 
} 

Ausgang:

[[20, 10, 30]] 
[[[20, 10, 30]]] 
[] 
[[]] 

Antwort

1

Wenn Sie hinzufügen SmallSet zu BigSet Sie fügen Sie den Satz selbst, nicht die Menge in seinem Inneren. So könnte man entweder

BigSet.add(new HashSet(SmallSet)); 

oder

BigSet.addAll(SmallSet); 

ich das persönlich später empfehlen. jedoch

Beachten Sie, dass, weil Sie hinzufügen die Set zu kleinen Satz, wenn Sie Folgendes haben:

Set<Integer> n = new HashSet<Integer>(Arrays.asList(10, 20, 30)); 
    SmallSet.add(n); 
    BigSet.addAll(SmallSet); 
    n.remove(20); 
    System.out.println(BigSet); 

Sie würden [10, 30] bekommen, weil es die SET ist und nicht die Set-Elemente, die zu BigSet hinzugefügt wurden .

Auch wenn ich an solchen Dingen in der Schule arbeitete, wurde mir dringend geraten, "Boxen" zu zeichnen - physische Boxen auf einer Tafel oder Whiteboard oder Papier. In diesem Fall möchten Sie vielleicht sogar Notizkarten verwenden und sie übereinander legen, um zu zeigen, was sich dort befindet. Es hilft wirklich, Ihr Gehirn darum zu wickeln.

+0

OP sagt, dass bigSet ein Satz Sets enthalten ist. Ich glaube nicht, dass OP nach den Elementen sucht, die hinzugefügt werden sollen. – sprinter

+0

Macht viel Sinn. BigSet.add (neues HashSet (SmallSet)) ist was ich gesucht habe. Danke – haxtar

+1

Ich werde sagen, dass 'BigSet.add (neue HashSet ...)' und 'BigSet.addAll (...) 'genau dasselbe, aber addAll ist doppelt so schnell, weil es nicht von' SmallSet' in das 'newHashSet' dumpen muss. Ich empfehle "addAll" über 'add (new' – corsiKa

1

Sie sind nicht korrekt, dass Sie bigSet löschen, wenn Sie smallSet löschen. smallSet ist immer noch in bigSet, es ist nur das ist es jetzt leer (weil Sie es gelöscht haben). Wenn Sie also [[]] von der print-Anweisung sehen, wird Ihnen mitgeteilt, dass bigSet jetzt eine einzelne, leere Menge enthält (speziell die jetzt leere smallSet).

Ich vermute, Ihr Missverständnis ist, dass Sie sich vorstellen, dass bigSet eine Kopie von smallSet nimmt, wenn Sie es hinzufügen. Es ist nicht. Es fügt einen Verweis auf dasselbe Objekt hinzu, auf das die Variable smallSet verweist. Wenn Sie smallSet.clear aufrufen, löschen Sie das Mengenobjekt, auf das sowohl von der Variablen als auch von bigSet verwiesen wird.

Wenn Sie tatsächlich eine Kopie smallSet innerhalb bigSet die einfachste Sache wollte einen neuen Satz zu tun wäre, zu erstellen, anstatt smallSet des Löschens:

bigSet.add(smallSet); 
smallSet = new HashSet<>(); 
+0

Du hast recht; das ist genau das, was ich sagen wollte. Ich denke, die Lösung ist ein neues HashSet von SmallSet, wie du sagst. Danke – haxtar

Verwandte Themen