Tôi biết LinkedHashMapcó một thứ tự lặp có thể dự đoán được (thứ tự chèn). Có phải Settrả lại bởi LinkedHashMap.keySet()và Collectiontrả lại bởi LinkedHashMap.values()cũng duy trì trật tự này?
Tôi biết LinkedHashMapcó một thứ tự lặp có thể dự đoán được (thứ tự chèn). Có phải Settrả lại bởi LinkedHashMap.keySet()và Collectiontrả 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ư
TreeMaplớp học, đảm bảo cụ thể theo thứ tự của chúng; những người khác, nhưHashMaplớ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 Mapvà LinkedHashMapđảm bảo nó.
Đó là điểm của lớp học này, sau tất cả.
Collectionchỉ 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 LinkedHashMaptrường hợp, nó trả về một LinkedValuesthể 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!
Setlà một giao diện với HashSet, TreeSetvv chúng sinh thực hiện. Việc HashSetthực hiện Setgiao diện không đảm bảo đặt hàng. Nhưng TreeSetkhông. Cũng LinkedHashSetcó.
Do đó, tùy thuộc vào cách Settriể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 LinkedHashMapnó, 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ó Settứ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 LinkedHashMapvà so sánh nó với phương pháp HashMaplàm nổi bật sự khác biệt chính giữa HashMapvà 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 Setvà 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.
LinkedHashMaplớ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.