Là thứ tự được đảm bảo cho việc trả lại các khóa và giá trị từ một đối tượng LinkedHashMap?


162

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()Collectiontrả lại bởi LinkedHashMap.values()cũng duy trì trật tự này?


1
Vì tất cả các câu trả lời đều đề cập đến vấn đề 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.
Duncan Jones

Câu trả lời:


226

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ư 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 ).

- LinkedHashMap

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 MapLinkedHashMapđảm bảo nó.

Đó là điểm của lớp học này, sau tất cả.


8
việc lặp lại trên bản đồ cũng được thực hiện nhanh hơn bằng cách sử dụng LinkedHashMap so với HashMap.
Thierry

2
giá trị () trả về một tập hợp. không phải là một danh sách Làm thế nào để nó giữ nó theo thứ tự?
Dejell

7
@Dejel 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.
Powerlord

2
Một bộ khóa của LinkedHashMap trong trường hợp của tôi KHÔNG theo thứ tự được thể hiện trong bản đồ. Rất hoang mang vì điều này.
Amalgovinus

2
Cảm ơn bạn đã liên kết với tài liệu (từ 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.
LarsH

11

Nhìn vào nguồn, có vẻ như nó làm. keySet(), values()entrySet()tất cả sử dụng cùng một iterator trong nội bộ.


1
Thật tuyệt khi có một liên kết đến các repos, nhưng tôi lười biếng :-) và tất nhiên, nó không đảm bảo khả năng tương thích về phía trước.
Ciro Santilli 郝海东 冠状 病 事件

6

Đừng nhầm lẫn với LinkedHashMap.keySet()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 HashMapLinkedHashMap.


4
Mặc dù câu trả lời này chắc chắn trình bày thông tin hữu ích, nhưng nó không thực sự trả lời câu hỏi. Về cơ bản nó nói rằng họ CÓ THỂ có thứ tự lặp có thể dự đoán được.
Tuupertunut

5

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 đồ 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 đó.


0

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.


Bạn có nghĩa là entryset () đảm bảo thứ tự, bởi keyset () không?
dùng256239

1
@kknight: Tôi không chắc. javadoc tuyên bố: "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).". Tuy nhiên, nói chung JavaDocs cho JDK rất mơ hồ.
Uri

5
Nếu ngay cả entryset () không đảm bảo thứ tự lặp, thì sự khác biệt giữa LinkedHashMap và HashMap là gì? Làm thế nào chúng ta có thể tận dụng thứ tự lặp có thể dự đoán được trong một cá thể LinkedHashMap?
dùng256239

1
Nó chắc chắn tài liệu. Trả lời là hoàn toàn không chính xác.
Hầu tước Lorne

-3

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.


3
Nhìn gần hơn vào các tài liệu, thực sự có đảm bảo. Như ai đó đã viết, đó là điểm chính của lớp này.
glglgl

-4

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.


6
Toàn bộ mục đích của 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.
zakinster
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.