2010-11-18 29 views
5

Tôi muốn có một đối tượng thực hiện cả giao diện Bản đồ và Danh sách trong Java. Ý tưởng này cũng tương tự như các vấn đề trong câu hỏi này: Java Ordered MapTriển khai cả giao diện Bản đồ và Danh sách trong Java?

Tôi muốn thêm cặp tên/giá trị cho một danh sách và có danh sách bảo tồn trình tự, mà còn có thể làm được tra cứu theo tên:

foo.put("name0", "value0"); 
foo.put("name1", "value1"); 
foo.get(1); --> Map.Entry("name1", "value1") 
foo.get("name0"); --> "value0" 

Dưới đây là các vấn đề: khi tôi tạo lớp này:

class Foo implements Map, List { 
    // add all methods here 
} 

tôi nhận được một lỗi biên dịch:

"The return type is incompatible with Map.remove(Object)" 
public boolean remove(Object o) { 
    return false; 
} 

Nếu tôi không triển khai giao diện Bản đồ và Danh sách, thì có rất nhiều phương pháp thu thập Java không có sẵn để sử dụng trên cấu trúc dữ liệu này.

(Ngoài ra, lý do mà các giải pháp được đề xuất trong Java Ordered Bản đồ ở trên không hoạt động là LinkedHashMap không có một phương pháp get (int). Không thể chọn các mục theo chỉ số.)

+2

Bạn có chống lại việc mở rộng 'LinkedHashMap', nếu không, tại sao không thử thêm phương thức' get (int) 'vào nó? –

+0

http://www.java.net/forum/topic/jdk/java-se/implementing-both-map-and-list-impossible-0 – Adam

+1

@Adam liên kết đó bị hỏng, nhưng tôi đoán chúng ta biết điều gì nó nói, chỉ từ URL;) – MatrixFrog

Trả lời

5

Khi bạn nhận thấy bạn không thể triển khai cả hai ListMap trên cùng một lớp. Nhưng đối với những gì bạn cần thì cũng không cần thiết. Những gì bạn cần là có thể truy cập data bằng cả giao diện Map và giao diện List. Một chút giống như truy cập dữ liệu Map làm một bộ trong entrySet() hoặc làm Bộ sưu tập bằng cách sử dụng Map.values().

Tóm lại, những gì bạn cần là 2 lượt xem trên dữ liệu, một chế độ xem đang triển khai List và chế độ xem khác đang triển khai Map.

Nếu có một chế độ xem chi phối (ví dụ Bản đồ) thì bạn có thể cung cấp phương pháp triển khai bản đồ List getAsList() trình bày dữ liệu dưới dạng Danh sách, được hỗ trợ bởi dữ liệu của Bản đồ.

EDIT

Câu trả lời được đưa ra bởi Paulo Guedes nên phục vụ quý khách. Đã có triển khai Bản đồ với các yêu cầu của bạn. Câu trả lời của tôi là tổng quát hơn một chút, về việc trình bày cùng một dữ liệu bằng cách sử dụng nhiều giao diện không tương thích trong đó một Adapter đơn giản là không đủ.

5

LinkedHashMap làm những gì bạn cần.

Bảng băm và triển khai danh sách liên kết của giao diện Bản đồ, với thứ tự lặp lại có thể dự đoán được. Triển khai này khác với HashMap ở chỗ nó duy trì một danh sách được liên kết kép đang chạy qua tất cả các mục nhập của nó.

+0

Không có phương thức 'get' để lấy các mục theo chỉ mục – Adam

+2

@Adam: Sau đó mở rộng LinkedHashMap và triển khai get (int index) bằng cách sử dụng trình lặp. Bạn thậm chí có thể sử dụng mảng sao lưu Entry [] gọi là 'table' (mặc dù tôi muốn sử dụng trình lặp cho độ mạnh). – extraneon

1

Giao diện MapList chứa định nghĩa xung đột của phương pháp remove. Bạn không thể thực hiện cả hai trong một lớp đơn vì bạn không thể ghi đè lên cùng một chữ ký phương thức với một sự khác biệt trong kiểu trả về chỉ.

Tôi tự hỏi nếu sử dụng List<Map.Entry<K,V>> sẽ đáp ứng nhu cầu của bạn.

5

Cần chỉ ra rằng lý do cho các lỗi là Map chứa các định nghĩa cho remove phương pháp sau đây:

V remove(Object key) 

Trong khi List định nghĩa:

boolean remove(Object o) 

Và, trong Java, các phương thức không thể bị quá tải dựa trên kiểu trả về của chúng, vì vậy chúng là các chữ ký xung đột và không thể được thực hiện trong cùng một lớp.

2

Tại sao bạn không triển khai giao diện của riêng mình?

public interface HashListMap { 

public boolean add(Object arg0); 
public void add(int arg0, Object arg1); 
public boolean addAll(Collection arg0); 
public boolean addAll(int arg0, Collection arg1); 
public void clear(); 
public boolean contains(Object arg0); 
public boolean containsAll(Collection arg0); 
public Object get(int arg0); 
public int indexOf(Object arg0); 
public boolean isEmpty(); 
public Iterator iterator(); 
public int lastIndexOf(Object arg0); 
public ListIterator listIterator(); 
public ListIterator listIterator(int arg0); 
public boolean remove(Object arg0); 
public Object remove(int arg0); 
public boolean removeAll(Collection arg0); 
public boolean retainAll(Collection arg0); 
public Object set(int arg0, Object arg1); 
public int size(); 
public List subList(int arg0, int arg1); 
public Object[] toArray(); 
public Object[] toArray(Object[] arg0); 
public boolean containsKey(Object arg0); 
public boolean containsValue(Object arg0); 
public Set entrySet(); 
public Object get(Object arg0); 
public Set keySet(); 
public Object put(Object arg0, Object arg1); 
public void putAll(Map arg0); 
public Collection values(); 

}

+2

+1 cho cảm giác hài hước –

+0

rất buồn cười :) điểm của việc sử dụng giao diện "không bao giờ được hỗ trợ" là gì? – Donatello

1

Ngoài những gì Dave Costa nói rằng bạn nên sử dụng LinkedHashMap. Đây là Bản đồ nhưng nó bảo tồn thứ tự chèn các phần tử.

Khi ánh xạ thực hiện phương thức values ​​(), bạn có thể nói new ArrayList (map.values ​​()). (0) để bắt chước chức năng danh sách.

nhưng bạn cũng có thể nói map.get ("một") vì nó chỉ là triển khai bản đồ.

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