2012-04-30 62 views
27

Xin chào Tôi có một LinkedHashMap (được gọi là thông tin) có chứa các cặp tên/tuổi (chuỗi/int). Tôi muốn tìm hiểu, làm cách nào tôi có thể lấy vị trí của khóa/giá trị nếu tôi nhập khóa. Ví dụ, nếu LinkedHashMap của tôi trông như thế này {bob = 12, jeremy = 42, carly = 21} và tôi đã tìm kiếm jeremy, nó sẽ trả về 1 như vị trí của nó 1. Tôi đã hy vọng tôi có thể sử dụng một cái gì đó như info.getIndex ("jeremy")Cách lấy vị trí khóa/giá trị trong LinkedHashMap bằng cách sử dụng khóa

+1

Xem [why-doesnt-linkedhashmap-provide-access-by-index] (http://stackoverflow.com/questions/5666820/why-doesnt-linkedhashmap-provide-access-by-index) – nawfal

Trả lời

22

HashMap triển khai nói chung không được đặt hàng cho Iteration.

LinkedHashMappredictablely ra lệnh cho Iteration (chèn theo thứ tự) nhưng không tiếp xúc với giao diện ListLinkedList (đó là những gì phản ánh trình tự bộ chèn key) không theo dõi vị trí index bản thân một trong hai, nó là rất trong- hiệu quả để tìm chỉ mục là tốt. LinkedHashMap cũng không hiển thị tham chiếu đến nội bộ LinkedList.

Thực tế "Danh sách được liên kết" là hành vi thực hiện cụ thể. Một số thực sự có thể sử dụng một phiên bản LinkedList một số chỉ có Entry theo dõi trước và sau Entry và sử dụng nó làm triển khai . Đừng giả sử bất cứ điều gì mà không cần nhìn vào nguồn.

KeySet có chứa khóa không đảm bảo trật tự cũng vì thuật toán băm được sử dụng cho vị trí trong cấu trúc dữ liệu sao lưu của di sản HashMap. Vì vậy, bạn không thể sử dụng điều đó. Cách duy nhất để thực hiện việc này, mà không cần viết bản thực hiện của riêng bạn, là đi bộ Iterator sử dụng số LinkedList phản chiếu và giữ nguyên vị trí của bạn, điều này sẽ rất hiệu quả với các tập dữ liệu lớn.

Giải pháp

gì có vẻ như bạn muốn là gốc để chèn chỉ số vị trí, bạn sẽ phải phản ánh các phím trong KeySet trong một cái gì đó giống như một ArrayList, giữ cho nó đồng bộ với bản cập nhật cho HashMap và sử dụng nó để tìm vị trí. Tạo một lớp con của HashMap, nói IndexedHashMap và thêm ArrayList nội bộ này và thêm .getKeyIndex(<K> key) ủy quyền cho nội bộ ArrayList.indexOf() có lẽ là cách tốt nhất để thực hiện việc này.

Đây là những gì LinkedHashMap làm nhưng với một LinkedList phản ánh số KeySet thay vì ArrayList.

+1

Tôi nghĩ LinkedHashMap giữ lại trật tự. Có điều gì tôi có thể sử dụng có thể lưu trữ khóa/giá trị nhưng vẫn giữ nguyên thứ tự? – Matt9Atkins

+1

Nó giữ lại, * trật tự * nhưng không theo dõi * vị trí *. –

+0

@ HernánEche đọc câu hỏi và câu trả lời cho hiểu, họ cũng muốn theo dõi vị trí, mà tôi đi vào chi tiết về câu trả lời của tôi. –

0

LinkedHashMap có "thứ tự lặp lại dự đoán" (javadoc). Tuy nhiên, các mặt hàng không biết vị trí của chúng, vì vậy bạn sẽ phải lặp lại bộ sưu tập để có được nó. Nếu bạn đang duy trì một bản đồ lớn, bạn có thể muốn sử dụng một cấu trúc khác để lưu trữ.

Edit: làm rõ lặp

+0

* "đi bộ phím' Set' sẽ không làm bạn bất kỳ tốt, nó được hỗ trợ bởi một 'Set', và nó là không được đặt hàng.' LinkedList' chỉ được sử dụng cho 'Iterator'. [Khi nghi ngờ sử dụng nguồn] (http://grepcode.com/file/repository.grepcode.com/java/root/jdk/openjdk/6-b14/java/util/HashMap.java#HashMap.keySet%28%29). –

+0

Thật vậy, tôi có nghĩa là mục nhập thiết lập.Đó là lý do tại sao một trích dẫn thứ tự bit lặp lại ... ngụ ý sử dụng iterator.Một sự lựa chọn của các từ trên một phần của tôi –

+0

Đoạn đầu tiên trong javadoc nói nó trong thứ tự chèn, đó là chính xác những gì ông hỏi Tôi nghĩ rằng chúng tôi đang nói cùng một điều ở đây, dù sao, các chỉnh sửa đã làm cho câu trả lời của bạn rõ ràng hơn –

0

Bạn có thể sử dụng com.google.common.collect.LinkedListMultimap từ thư viện Google Ổi.Bạn không cần hành vi multimap của lớp này mà bạn muốn là phương thức keys() đảm bảo chúng được trả về theo thứ tự chèn và sau đó có thể được sử dụng để xây dựng Danh sách, bạn có thể sử dụng indexOf() để tìm vị trí chỉ mục yêu cầu

9
int pos = new ArrayList<String>(info.keySet()).indexOf("jeremy") 
+1

Afaik lệnh' keySet() ' không được bảo đảm. – membersound

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