2010-11-18 77 views
5

我想要一個在Java中實現Map和List接口的對象。我們的想法是在這個問題類似的問題:Java Ordered Map在Java中實現Map和List接口嗎?

我想名稱/值對添加到列表中,並有列表保存序列,也可以通過做名字查找:

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

這裏的問題:當我創建這個類:

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

我得到一個編譯錯誤:

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

如果我沒有實現Map和List接口,那麼有很多Java集合方法不可用於此數據結構。

(同樣,在Java中提出的解決方案上面的有序地圖不起作用的原因是,LinkedHashMap中沒有一個get(int)方法。無法通過索引選擇項。)

+2

您是否反對擴展'LinkedHashMap',如果沒有,爲什麼不嘗試向其添加'get(int)'方法? – 2010-11-18 19:20:20

+0

http://www.java.net/forum/topic/jdk/java-se/implementing-both-map-and-list-impossible-0 – Adam 2010-11-18 19:22:08

+1

@Adam鏈接被破壞,但我想我們知道什麼它說,只是從URL;) – MatrixFrog 2011-06-23 21:54:11

回答

5

正如你所注意到的,你不能在同一個類上實現ListMap。但是對於你所需要的,也不是必須的。您需要的是data可以通過MapList接口進行訪問。有點像在entrySet()中訪問Map數據集或使用Map.values()作爲集合。

總之,您需要的是2個數據視圖,一個視圖實現List,另一個視圖實現Map

如果有一個視圖佔優勢(例如Map),那麼你可以給你的地圖實現一個方法List getAsList(),它將數據顯示爲一個List,並由Map的數據支持。

編輯

由聖保羅古埃德斯給出的答案應該爲您服務。已經有一個Map實現了你的需求。我的答案是更一般的,關於使用多個不兼容的接口提供相同的數據,其中一個簡單的適配器是不夠的。

5

LinkedHashMap做你需要的。

哈希表和Map接口的鏈表實現,具有可預測的迭代順序。這個實現與HashMap的不同之處在於它保持了一個雙向鏈表,它貫穿其所有條目。

+0

沒有'get'方法通過索引獲得項目 – Adam 2010-11-18 19:24:36

+2

@Adam:然後擴展LinkedHashMap並使用迭代器實現get(int index)。你甚至可以使用名爲'table'的支持Entry []數組(儘管我使用迭代器來實現健壯性)。 – extraneon 2010-11-18 19:31:01

1

MapList接口包含remove方法的衝突定義。您無法在單個類中實現這兩種功能,因爲您無法僅覆蓋返回類型不同的相同方法簽名。

我想知道如果使用List<Map.Entry<K,V>>會滿足您的需求。

5

應該指出的是,該錯誤的原因是,Map包含以下remove方法的定義:

V remove(Object key) 

雖然List定義:

boolean remove(Object o) 

而且,在Java中,方法不能基於它們的返回類型被重載,所以它們是衝突的簽名,並且不能在相同的類中實現。

2

爲什麼不實現自己的界面?

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爲幽默感 – 2010-11-18 21:48:04

+0

非常有趣:)使用「從不支持」界面的要點是什麼? – Donatello 2018-01-18 11:11:39

1

除了戴夫哥說你應該使用LinkedHashMap的。這是Map,但它保留了元素插入的順序。

由於它實現了values()方法,所以你可以說 新的ArrayList(map.values())。get(0) 來模仿列表功能。

但你也可以說 map.get(「one」) 因爲它只是一個地圖實現。