2011-10-20 31 views
5

Tôi đang gặp sự cố khi nhận bản sao HashMaps riêng của mình. Ý tôi là, một khi tôi đã tạo một bản sao của bản gốc, việc thay đổi bản gốc sẽ không thay đổi bản gốc.Hành vi sao chép HashMap Tôi không thể tìm ra

Tôi có hai HashMaps ở định dạng này:

HashMap<String, List<String> one = new HashMap<String, List<String>(); 
HashMap<String, List<String> two = new HashMap<String, List<String>(); 

Tôi gọi hàm sau bên dưới (getTabSetDifferences) đi qua trong một và hai, như mong đợi nếu có một số khác biệt, những giá trị này sẽ được loại bỏ khỏi HashMap và nó sẽ khác so với trước khi nó được thông qua cho thử nghiệm.

Tôi muốn họ vẫn không thay đổi, vì vậy cố gắng passsing trong:

getTabSetDifferences((HashMap)one.clone(), (HashMap)two.clone()) 

này vẫn thay đổi bản gốc, vì vậy tôi tạo thêm hai hashmaps trong các định dạng tương tự, và nhân bản một và hai đối với họ, tôi đã sử dụng các hashmaps mới để vượt qua trong và bản gốc vẫn được thay đổi.

sau đó tôi đã cố gắng:

HashMap<String, List<String>> holdOne = new HashMap<String, List<String>>(); 
holdOne.putAll(one); 

HashMap<String, List<String>> Holdtwo = new HashMap<String, List<String>>(); 
holdTwo.putAll(two); 

Bây giờ tôi có thể làm điều gì đó như:

holdTwo.remove(key); 

và bản gốc là không thay đổi, nhưng nếu tôi gọi phương thức với holdOne và holdTwo nó vẫn thay đổi ban đầu một và hai hashmaps, không nên họ vẫn còn? Phương pháp này hoạt động và tìm ra sự khác biệt mà tôi muốn và được trả lại. Nhưng tôi vẫn cần hai bản gốc hashmaps để được như họ được, nhưng không có vấn đề mà cách tôi gọi, những gì bao giờ thay đổi được thực hiện để giữOne và holdTwo thay đổi bản gốc. Đó có phải là hành vi mong đợi không? Nếu vậy, cách thích hợp là để có được một bản sao của một băm không liên kết với nó.

getTabSetDifferences(holdOne, holdTwo); 

public HashMap<String, List<String>> getTabSetDifferences(HashMap<String, List<String>> hmMain, HashMap<String, List<String>> hmSecond) { 
    HashMap<String, List<String>> hmDifferences = new HashMap<String, List<String>>(); 
    for (Map.Entry<String, List<String>> entry : hmMain.entrySet()) { 
     if(hmSecond.containsKey(entry.getKey())) { 
      entry.getValue().removeAll(hmSecond.get(entry.getKey())); 
      if (entry.getValue().size() > 0) 
       hmDifferences.put(entry.getKey(), entry.getValue()); 
     } 
     else { 
      hmDifferences.put(entry.getKey(), entry.getValue()); 
     } 
    } 
    return hmDifferences; 
} 
+0

giải thích của bạn không rõ ràng. Tôi không hiểu những gì bạn đang cố gắng làm và làm thế nào nó không thành công – Bozho

+0

Nó không thực sự thất bại. Tôi đang tìm cách giữ nguyên hai HashMaps ban đầu của mình. Phương thức getTabSetDifferences loại bỏ sự khác biệt so với một trong các phương thức được truyền trong HashMaps. Tôi muốn chuyển vào một bản sao, vì vậy bản gốc không thay đổi, nhưng tôi không thể tìm ra cách tạo một bản sao, mà không được gắn với bản gốc. – Green

Trả lời

2

Phương pháp sao chép không làm bản sao sâu.

Bạn có 2 tùy chọn.

  1. tạo phương pháp sao chép sâu.
  2. Sử dụng một trong những triển khai Bản đồ từ gói java.util.concurrent như copyOnWrite
+1

Tôi đã viết phương pháp sao chép sâu của riêng mình. làm việc tốt. cảm ơn sự chỉ đạo. – Green

2

Tôi nghi ngờ bạn chỉ sao chép khóa/giá trị. Điều này sẽ không tạo bản sao của danh sách.

Có lẽ Bản đồ đa năng của Guava là những gì bạn muốn?

2

Nếu bạn sao chép danh sách như một danh sách (tức là sao chép nó vào phạm vi danh sách, chứ không phải là một số thực hiện cấp dưới) , sau đó hành vi con trỏ sẽ được nhìn thấy .... Tuy nhiên nếu bạn sao chép từ một danh sách vào một danh sách mới, thì những đối tượng chuỗi đó là độc lập.

Phương pháp sao chép của Java không nên được sử dụng với kỳ vọng rằng nó sẽ trả về các bản sao riêng biệt, sâu sắc của một đối tượng - bất biến không phải là một khái niệm trung tâm cho cách sao chép.

Tôi đồng ý với nhận xét ở trên: sử dụng multimap trong thư viện như guava hoặc bộ sưu tập của google hoặc đơn giản là cẩn thận về việc sao chép của bạn và chỉ sao chép ở cấp độ gốc. và hy vọng nó sẽ độc lập) trừ khi bạn đã kiểm tra điều này một cách rõ ràng.

Các vấn đề liên quan