2011-11-08 30 views
8

Tôi cần kết hợp một số dữ liệu với khóa cho toàn bộ thời gian của nó, vì vậy tôi đang sử dụng WeakHashMap. Tuy nhiên, ngoài ra tôi cần phải có được một khóa bằng giá trị tương ứng của nó. Cách đơn giản để làm điều đó là để giữ cho tài liệu tham khảo khi tạo một giá trị:Mục nhập WeakHashMap có được thu thập nếu giá trị chứa tham chiếu mạnh duy nhất cho khóa không?

public class Key {} 

public class Value { 
    final public Key key; 
    public Value(Key k) { 
     key = k; 
    } 
} 

Tất nhiên, khi tôi sử dụng Value trong chương trình của tôi, key của nó sẽ không biến mất. Tuy nhiên, nếu không có thêm tham chiếu đến một trong hai khóa hoặc giá trị của nó bên ngoài bản đồ, nó sẽ là rác được thu thập? Hay tham chiếu mạnh mẽ còn sống sót trong giá trị có ngăn cản nó không?

Trả lời

13

Không nó sẽ không được thu gom rác thải, xem Javadoc: lưu ý

thực hiện: Các đối tượng giá trị trong một WeakHashMap được tổ chức bởi tài liệu tham khảo mạnh bình thường. Vì vậy, cần thận trọng để đảm bảo rằng các đối tượng giá trị không tham chiếu mạnh mẽ đến khóa riêng của chúng, trực tiếp hoặc gián tiếp, vì điều đó sẽ ngăn chặn các khóa bị loại bỏ.

Như đã đề cập bởi @biziclop một giải pháp là lưu trữ tham chiếu yếu vào khóa trong đối tượng giá trị của bạn.

public class Value { 
    final public WeakReference<Key> key; 
    public Value(Key k) { 
    this.key = new WeakReference<Key>(k); 
    } 
} 
+1

+1 Có lẽ tôi đã đọc tài liệu trước. :) – biziclop

+0

@biziclop Cũng từ Javadoc: Một cách để giải quyết vấn đề này là tự bọc các giá trị trong WeakReferences trước khi chèn, như sau: m.put (key, new WeakReference (value)), và sau đó unwrapping khi nhận được. Điều đó sẽ thực hiện thủ thuật! – laguille

+0

Hoặc chỉ lưu trữ một tham chiếu yếu đến khóa trong đối tượng giá trị của bạn. Bởi vì nếu bạn quấn giá trị trong một WR, bạn có thể kết thúc với một khóa hiện có với giá trị alraedy thu thập được. – biziclop

2

Nhìn vào triển khai, câu trả lời dường như là không.

Đây là từ nguồn WeakHashMap:

/** 
* The table, resized as necessary. Length MUST Always be a power of two. 
*/ 
private Entry[] table; 

... 

private static class Entry<K,V> extends WeakReference<K> implements Map.Entry<K,V> { 
    private V value; 
    ... 
} 

Như bạn thấy, Entry đối tượng được tham chiếu mạnh mẽ bởi chính bản đồ. Vì vậy, nếu bản đồ có thể truy cập được, do đó, sẽ là Entry, do đó, các đối tượng Value cũng như khóa của bạn cũng vậy.

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