Tôi biết LinkedHashMap
có một thứ tự lặp có thể dự đoán được (thứ tự chèn). Có phải Set
trả lại bởi LinkedHashMap.keySet()
và Collection
trả lại bởi LinkedHashMap.values()
cũng duy trì trật tự này?
Tôi biết LinkedHashMap
có một thứ tự lặp có thể dự đoán được (thứ tự chèn). Có phải Set
trả lại bởi LinkedHashMap.keySet()
và Collection
trả lại bởi LinkedHashMap.values()
cũng duy trì trật tự này?
Câu trả lời:
Giao diện Bản đồ cung cấp ba chế độ xem bộ sưu tập , cho phép xem nội dung của bản đồ dưới dạng một bộ khóa, bộ sưu tập các giá trị hoặc bộ ánh xạ giá trị khóa. Thứ tự của bản đồ được định nghĩa là thứ tự mà các trình vòng lặp trên chế độ xem bộ sưu tập của bản đồ trả về các phần tử của chúng. Một số triển khai bản đồ, như
TreeMap
lớp học, đảm bảo cụ thể theo thứ tự của chúng; những người khác, nhưHashMap
lớp học, thì không.
- Bản đồ
Danh sách được liên kết này xác định thứ tự lặp, thường là thứ tự các phím được chèn vào bản đồ ( thứ tự chèn ).
Vì vậy, có, keySet()
, values()
, và entrySet()
(ba lần xem bộ sưu tập đề cập) giá trị trả về theo thứ tự những ứng dụng danh sách liên kết nội bộ. Và vâng, JavaDoc cho Map
và LinkedHashMap
đảm bảo nó.
Đó là điểm của lớp học này, sau tất cả.
Collection
chỉ là lớp cơ sở cho những gì giá trị () trả về. Việc thực hiện Bộ sưu tập mà nó trả về vẫn được kiểm soát bởi LinkedHashMap
. Trong LinkedHashMap
trường hợp, nó trả về một LinkedValues
thể hiện, một lớp riêng trong LinkedHashMap.java.
Map
) liên kết rõ ràng thứ tự của bản đồ với các trình lặp trên các chế độ xem bộ sưu tập của bản đồ (và làm rõ các chế độ xem bộ sưu tập đó là gì). Đó là mảnh còn thiếu cho tôi.
Nhìn vào nguồn, có vẻ như nó làm. keySet()
, values()
và entrySet()
tất cả sử dụng cùng một iterator trong nội bộ.
Đừng nhầm lẫn với LinkedHashMap.keySet()
và LinkedHashMap.entrySet()
trả về Set và do đó nó không đảm bảo việc đặt hàng!
Set
là một giao diện với HashSet
, TreeSet
vv chúng sinh thực hiện. Việc HashSet
thực hiện Set
giao diện không đảm bảo đặt hàng. Nhưng TreeSet
không. Cũng LinkedHashSet
có.
Do đó, tùy thuộc vào cách Set
triển khai LinkedHashMap
để biết liệu tham chiếu Set trả về có đảm bảo đặt hàng hay không. Tôi đã đi qua mã nguồn của LinkedHashMap
nó, nó trông như thế này:
private final class KeySet extends AbstractSet<K> {...}
public abstract class AbstractSet<E> extends AbstractCollection<E> implements Set<E> {...}
Do đó LinkedHashMap / HashMap có triển khai riêng của nó Set
tức là KeySet
. Do đó, đừng nhầm lẫn điều này với HashSet
.
Ngoài ra, thứ tự được duy trì bằng cách các phần tử được chèn vào thùng. Nhìn vào addEntry(..)
phương pháp LinkedHashMap
và so sánh nó với phương pháp HashMap
làm nổi bật sự khác biệt chính giữa HashMap
và LinkedHashMap
.
Bạn có thể giả định như vậy. Javadoc nói 'thứ tự lặp có thể dự đoán được' và các trình lặp duy nhất có sẵn trong Bản đồ là các thứ tự cho keyset (), entryset () và value ().
Vì vậy, trong trường hợp không có bất kỳ trình độ chuyên môn nào nữa, rõ ràng nó được dự định áp dụng cho tất cả các trình vòng lặp đó.
AFAIK nó không được ghi lại để bạn không thể "chính thức" giả định như vậy. Tuy nhiên, không chắc là việc triển khai hiện tại sẽ thay đổi.
Nếu bạn muốn đảm bảo trật tự, bạn có thể muốn lặp lại các yêu cầu của bản đồ và chèn chúng vào một tập hợp được sắp xếp với chức năng đặt hàng theo lựa chọn của bạn, mặc dù bạn sẽ phải trả chi phí hiệu suất.
Nhìn vào giao diện, nó trả về một đơn giản Set
và không phải là một SortedSet
. Vì vậy, không có đảm bảo.
Trước khi giả định một bảo đảm ngầm bằng cách xem xét việc triển khai (luôn luôn là một ý tưởng tồi) cũng hãy xem các triển khai trong tất cả các triển khai Java khác :)
Ví dụ, bạn có thể tạo một TreeSet với keyset trong hàm tạo.
Tôi không nghĩ rằng bạn có thể đoán được thứ tự của keyset () và value ().
Tôi có thể dễ dàng viết một triển khai LinkedHashMap trả về cho bạn keyset () và giá trị () không có thứ tự, miễn là tôi tuân theo hợp đồng của hai phương thức được xác định trong Map và được ghi đè trong HashMap.
LinkedHashMap
lớp là giữ trật tự của các yếu tố trong khi lặp lại bản đồ và hành vi này được chỉ định rõ. Nếu bạn viết một lớp con mà không tuân thủ đặc tả của lớp cơ sở, thì bạn đang làm điều gì đó rất sai.
values()
cũng nhưkeySet()
, tôi đã mở rộng câu hỏi để đưa vào đó. Điều này có nghĩa là nhiều câu hỏi có thể được đóng lại như là bản sao của điều này.