2012-11-27 30 views
30

Tôi cóCách lấy giá trị từ LinkedHashMap dựa trên chỉ mục không phải trên khóa?

LinkedHashMap<String, List<String>> hMap; 

Tôi muốn nhận List<String> bởi vị trí không phải trên chìa khóa.

Tôi không muốn sử dụng lặp lại.

Có cách nào khác để nhận Giá trị dựa trên chỉ mục không?

+2

Nếu bạn chọn cấu trúc dữ liệu này một mình thì có lẽ nó không phải là tốt nhất cho nhiệm vụ này. –

+0

@NikolayKuznetsov: bạn có thể gợi ý cho tôi cấu trúc của nó không? – MAC

+0

ArrayList nếu bạn trích xuất các phần tử chỉ bằng chỉ mục –

Trả lời

41

Bạn không thể nhận được giá trị của Map dựa trên chỉ số, Map s chỉ không làm việc theo cách đó. Cách giải quyết là tạo danh sách mới từ các giá trị của bạn và nhận giá trị dựa trên chỉ mục.

LinkedHashMap<String, List<String>> hMap; 
List<List<String>> l = new ArrayList<List<String>>(hMap.values()); 
l.get(0); 
+2

Nếu tôi muốn chèn giá trị dựa trên chỉ mục? làm thế nào để đạt được điều đó? –

+1

Đây là câu trả lời tôi đã đăng cho dù sao đi nữa, tôi không thể đăng nó ở đây, chủ đề này bị khóa: http://stackoverflow.com/a/31749969/961018 – momomo

13
public List<String> getByIndex(LinkedHashMap<String, List<String>> hMap, int index){ 
    return (List<String>) hMap.values().toArray()[index]; 
} 
9

bạn có thể muốn xem xét sử dụng một lớp khác để lưu trữ dữ liệu của bạn hoặc viết phần mở rộng cho liên kếtHashMap. giống như

//this is pseudo code 
public class IndexedLinkedHashMap<K,V> extends LinkedHashMap{ 

HashMap<int,K> index; 
int curr = 0; 

    @Override 
    public void add(K key,V val){ 
     super.add(key,val); 
     index.add(curr++, key); 
    } 

    public V getindexed(int i){ 
     return super.get(index.get(i)); 
    } 

} 
3

Không có DS trực tiếp trong API bộ sưu tập Java chuẩn để cung cấp bản đồ được lập chỉ mục. Tuy nhiên, sau đây sẽ cho phép bạn đạt được kết quả:

// An ordered map 
Map<K, V> map = new LinkedHashMap<K, V>(); 
// To create indexed list, copy the references into an ArrayList (backed by an array) 
List<Entry<K, V>> indexedList = new ArrayList<Map.Entry<K, V>>(map.entrySet()); 
// Get the i'th term 
<Map.Entry<K,V>> entry = indexedList.get(index); 
K key = entry.getKey(); 
V value = entry.getValue(); 

Bạn vẫn có thể muốn giữ lại những mối quan tâm của dữ liệu bền bỉ trong bản đồ riêng biệt từ việc thu hồi.

Cập nhật: Hoặc sử dụng LinkedMap từ Apache Commons.

5

Như Kevin Bowersox nói, nó đơn giản như

List<String> result = (List<String>) hMap.values().toArray()[position]; 

Nhưng cần lưu ý rằng điều này vẫn sẽ lặp bằng cách sử dụng .toArray(). Đó là một tuyên bố đơn giản và tôi không chắc chắn nếu có một với hiệu suất tốt hơn, nhưng lưu ý rằng sự phức tạp không phải là log (n) (như truy cập được lập chỉ mục trong trường hợp B *), nhưng chỉ n. Vì LinkedHashMap dựa trên LinkedList, không có cách nào để truy cập ngẫu nhiên các phần tử, chỉ theo thứ tự tuần tự.

Việc truyền vào Danh sách là một điều ác không thể tránh khỏi, vì .toArray() tuân theo khái niệm cổ xưa về việc trả về đối tượng thay vì kiểu dữ liệu chung.

Mặc dù điều này có thể không phải là khái niệm chính của bản đồ, nhưng LinkedHashMap không chỉ là bản đồ. nó mở rộng HashMap, và như là một lớp mở rộng, nó hoàn toàn tốt để mang lại các phương thức bổ sung hỗ trợ các idiosyncracies của lớp đó.

+0

tạo một mảng mới ..không phải là rất đẹp – momomo

+1

Đây là một câu trả lời tôi được đăng cho dù sao đi nữa, tôi không thể đăng nó ở đây, chủ đề này bị khóa: http://stackoverflow.com/a/31749969/961018 – momomo

+0

@momo Bài viết của tôi chỉ đơn giản là để giải thích rằng những gì Kevin Bowersox đề xuất không tránh lặp lại và hơn nữa là không có cách nào như vậy. Việc tạo ra một mảng có thể dễ dàng tránh được bằng cách lặp lại các giá trị theo cách thủ công, nhưng đó không phải là câu trả lời lý tưởng khi câu hỏi là làm thế nào để thực hiện nó mà không cần lặp lại. Rõ ràng bạn có thể tránh điều đó bằng cách tạo ra các triển khai của riêng bạn với một khái niệm lập chỉ mục khác, nhưng điều đó dường như không liên quan đến câu hỏi. – makrom

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