Tại sao tồn tại WeakHashMap, nhưng không có WeakSet?


76

Của J. Bloch

Một ... nguồn rò rỉ bộ nhớ là người nghe ... Cách tốt nhất để đảm bảo rằng các cuộc gọi lại được thu thập kịp thời là chỉ lưu trữ các tham chiếu yếu đến chúng, chẳng hạn bằng cách chỉ lưu trữ chúng dưới dạng khóa trong WeakHashMap .

Vì vậy, tại sao không có bất kỳ WeakSet nào trong khung Java Collections ?


1
Stas, bạn có thể chấp nhận câu trả lời đúng, được ủng hộ của mart thay vì câu trả lời không chính xác của Martin không?
toolforger

Trong khi Joshua Bloch đã viết rất nhiều lời khuyên hợp lý cho các lập trình viên Java, đây dường như là một ngoại lệ khủng khiếp. Việc lưu trữ người nghe vào một WeakHashMapkhông bao giờ “đảm bảo rằng các cuộc gọi lại được thu thập kịp thời”, mà ngược lại, khiến chúng trở nên không xác định một cách khủng khiếp. Bộ thu gom rác sẽ chỉ chạy khi không có đủ bộ nhớ, do đó, những người nghe yếu như vậy có thể bị treo lơ lửng trong một thời gian dài tùy ý và vẫn được thực thi , nhưng thậm chí tệ hơn, những người nghe như vậy có thể biến mất một cách nhanh chóng khi bạn vẫn cần chúng, vì nó bây giờ cần một thực sự không liên quan đến tham chiếu mạnh mẽ để giữ cho họ sống.
Holger

Câu trả lời:


194
Set<Object> weakHashSet = Collections.newSetFromMap(
        new WeakHashMap<Object, Boolean>());

Như đã thấy trong Collections.newSetFromMaptài liệu, chuyển a WeakHashMapđể lấy a Set.


4
thực sự bất kỳ Set trong bộ sưu tập java đều chứa Bản đồ để lưu trữ.
mart,

4
Đúng, nhưng tại sao không có lớp cụ thể cho những thứ như vậy?
Stan Kurilin,

14
Thật dễ dàng để tưởng tượng tại sao những người bảo trì java.util có thể muốn ngừng cung cấp các phiên bản Bản đồ và Bộ kép của mọi thứ họ làm và chọn chỉ cung cấp newSetFromMap () thay thế ... phải không?
Kevin Bourrillion,

24
Cần lưu ý rằng Collections # newSetFromMap bị thiếu trong Android trước API 9. Không khó để tìm thấy một triển khai để biên dịch vào ứng dụng của bạn, nhưng đó là một sự tương thích.
nmr

3
@Mike JavaDoc đúng. Lưu ý rằng mã trong câu trả lời này trả về một Tập hợp các đối tượng không phải là Boolean. newSetFromMaptạo một tập hợp các loại khóa, không phải các giá trị.
kabuko

14

Vì vậy, tại sao không có bất kỳ WeakSet nào trong khung thu thập java?

Câu trả lời thực sự chính xác duy nhất cho điều đó là chúng tôi không thể cho bạn biết lý do tại sao vì chúng tôi không phải là người đưa ra quyết định thiết kế. Chỉ các nhà thiết kế Java mới biết lý do tại sao họ đưa ra quyết định 1 .


Mặc dù có thể có các trường hợp sử dụng hạn chế WeakHashSet, một phần của triết lý thiết kế thư viện lớp Java là tránh đưa các thư viện lớp vào các lớp tiện ích cho tất cả các trường hợp sử dụng có thể có.

Có một số thư viện lớp khác bao gồm các loại bộ sưu tập; Apache Commons Collections và Google Collections (hay còn gọi là Guava) là những ví dụ điển hình. Tuy nhiên, WeakHashSetthậm chí chưa "cắt giảm" cho các thư viện Apache và Google.

Và, tất nhiên, bạn có thể sử dụng Collections.newSetFromMapđể bọc một WeakHashMapphiên bản.


1 - Tranh luận về tính đúng đắn của quyết định đó nằm ngoài phạm vi của StackOverflow. Đây là một trang hỏi đáp, không phải diễn đàn thảo luận.


Cảm ơn. Có lẽ tôi cần làm thêm công việc quan sát về các thư viện khác để hiểu khung sưu tập java.
Stan Kurilin,

“Các trường hợp sử dụng hạn chế cho WeakHashSet”? Tiến sĩ Bloch đã cung cấp cho bạn một trường hợp sử dụng rất phổ biến như được trích dẫn trong Câu hỏi.
Basil Bourque

Trích dẫn Bloch đang mô tả một trường hợp sử dụng cho WeakHashMap không WeakHashSet. Anh ấy có đề cập cụ thể đến việc không có bộ băm yếu như một vấn đề không? Nếu không, thì bạn không thể yêu cầu anh ta là người có thẩm quyền cho tuyên bố của bạn rằng đó là một vấn đề. Dù sao đây cũng là Q&A, không phải tranh luận. Tôi chỉ trả lời câu hỏi của OP với câu trả lời mà các nhà thiết kế Java thường đưa ra vì không bao gồm những thứ như thế này. Cho dù bạn (hoặc OP) đồng ý là ... bên cạnh vấn đề.
Stephen C

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.