2016-08-23 57 views
1

我有個疑問,我想檢查一下java中的TreeSet是否真的爲它的clone()使用了淺拷貝,但是如果我從父樹set中移除了一個元素,那麼它不會反映在它的克隆的treeset對象中。Treeset的clone()的證明在java中創建淺拷貝?

public class TreeSetExample { 
    public static void main(String[] args) { 
     TreeSet<Name> nameTreeSet = new TreeSet<>(); 
     nameTreeSet.add(new Name("Compiere")); 
     nameTreeSet.add(new Name("Aristotle")); 
     nameTreeSet.add(new Name("CompierE")); 
     nameTreeSet.add(new Name("COmpiere")); 
     nameTreeSet.add(new Name("ArisTotle")); 
     nameTreeSet.add(new Name("arisTotle")); 
     nameTreeSet.add(new Name("aristotle")); 
     System.out.println(nameTreeSet); 

     TreeSet<Name> cloneNameTreeSet = (TreeSet<Name>) nameTreeSet.clone(); 
     System.out.println(nameTreeSet); 
     Iterator<Name> itr = nameTreeSet.iterator(); 

     /*while (itr.hasNext()) { 
      if (itr.next().getName().equals("aristotle")) 
       itr.remove(); 
     }*/ 

     for(Name name: nameTreeSet) { 
      if(name.getName().equals("aristotle")) 
       nameTreeSet.remove(name); 
     } 

     System.out.println(nameTreeSet); 
     System.out.println(cloneNameTreeSet); 
    } 
} 

/* 
*Name class which is used in my treeset to store its objects 
*/ 

public class Name implements Cloneable, Comparable<Name>, Comparator<Name> { 
    @Override 
    public String toString() { 
     return "Name [name=" + name + "]"; 
    } 

    private String name; 

    public Name(String name) { 
     super(); 
     this.name = name; 
    } 

    public String getName() { 
     return name; 
    } 

    public void setName(String name) { 
     this.name = name; 
    } 

    @Override 
    public int hashCode() { 
     final int prime = 31; 
     int result = 1; 
     result = prime * result + ((name == null) ? 0 : name.hashCode()); 
     return result; 
    } 

    @Override 
    public boolean equals(Object obj) { 
     if (this == obj) 
      return true; 
     if (obj == null) 
      return false; 
     if (getClass() != obj.getClass()) 
      return false; 
     Name other = (Name) obj; 
     if (name == null) { 
      if (other.name != null) 
       return false; 
     } else if (!name.equals(other.name)) 
      return false; 
     return true; 
    } 

    @Override 
    public int compare(Name name1, Name name2) { 
     return name1.name.compareTo(name2.name); 
    } 

    @Override 
    public int compareTo(Name name) { 
     return (this.name).compareTo(name.name); 
    } 

} 
+0

請給我建議,更正非常感謝:) – Arafath

+1

爲什麼你會期望一個元素被從克隆的實例中刪除,如果你從原來的刪除它? 'clone()'創建一個單獨的實例,具有單獨的狀態,因此原始中的更改不會反映在克隆中(反之亦然) –

+0

淺拷貝仍然是副本:您可以更改一個,而不會影響另一個。 – khelwood

回答

4

如果刪除從父TreeSet中一個元素,其並不將其克隆TreeSet中物體反射。

你是誤解淺拷貝的意思。這意味着對於TreeSet的每個元素,該參考被複制到新的TreeSet。因此,如果您更改位於一個Set中的Name對象之一,則其他Set中的相應元素也將發生變異,因爲兩者都引用同一個對象。

例如,這將同時影響Set S:

for(Name name: nameTreeSet) { 
     if(name.getName().equals("aristotle")) 
      name.setName("new name"); 
    } 

然而,克隆TreeSet是不同的對象比原來TreeSet,併除去從一個元素不影響其他。僅當從一個Set中刪除元素時,纔會影響其他元素,而不是隻複製參考文件 - TreeSet<Name> cloneNameTreeSet = nameTreeSet;

+0

感謝您的努力,但現在我仍然與淺拷貝和深拷貝混淆,請幫助我更好地瞭解 – Arafath

+2

@arafath深拷貝將意味着原始TreeSet的副本將包含所有Name元素的副本(而不是引用存儲在原始TreeSet中的相同Name元素)。 – Eran

+0

謝謝@Eran – Arafath