2010-11-18 16 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; 
} 

マップとリストのインターフェースを実装していない場合、このデータ構造では使用できないJavaコレクションのメソッドがたくさんあります。

(また、Javaで提案された解決策は、上記の地図を発注した理由は動作しないのLinkedHashMapは、get(int)メソッドを持っていないということである。インデックスでエントリを選択することはできません。)

+2

'LinkedHashMap'を拡張しないのですか?そうでない場合は、' get(int) 'メソッドを追加してみてください。 –

+0

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

+1

@Adamそのリンクは壊れていますが、 URLからちょうど); – MatrixFrog

答えて

5

お気づきのように、ListMapの両方を同じクラスに実装することはできません。しかし、あなたが必要とするものについては、それは必要ではないはずです。必要なのはdataMapListの両方のインターフェイスでアクセスできることです。ちょっとentrySet()のセットとしてMapデータにアクセスするか、Map.values()を使用してコレクションとしてアクセスするようなビットです。

要するに、データ上に2つのビューがあり、1つのビューはListを実装し、もう1つのビューはMapを実装しています。

ビュードミナント(Mapなど)が1つある場合は、マップのデータに基づいてデータをリストとして表示するメソッドList getAsList()をマップ実装に与えることができます。

EDIT

パウロGuedesのによって与えられた答えはあなたを提供すべきです。あなたの要件を満たすMap実装がすでにあります。私の答えは、単純なアダプタでは不十分な複数の互換性のないインターフェイスを使用して同じデータを提示するという点で、もう少し一般的です。

5

LinkedHashMapあなたが必要とすることをします。

Mapインターフェイスのハッシュテーブルとリンクリストの実装で、予測可能な繰り返し順序を使用します。この実装は、すべてのエントリを実行する二重リンクリストを維持するという点でHashMapとは異なります。

+0

インデックスで項目を取得する 'get'メソッドはありません。 – Adam

+2

@Adam:LinkedHashMapを拡張し、イテレータを使用してget(int index)を実装します。 'table'というバッキングEntry []配列を使用することもできます(ただし、頑健性のためにイテレータを使用します)。 – extraneon

1

MapおよびListインターフェイスには、removeメソッドの矛盾する定義が含まれています。戻り値の型の違いだけで同じメソッドのシグネチャをオーバーライドすることはできないため、両方を単一のクラスに実装することはできません。

List<Map.Entry<K,V>>を使用するのがあなたの必要を満たすのだろうかと思います。

5

エラーの原因がMapは以下のremoveメソッドの定義が含まれていることであることを指摘しなければならない:

V remove(Object key) 

Listが定義されている間:

boolean remove(Object o) 

そして、Javaでの、メソッドは戻り値の型に基づいてオーバーロードすることはできません。したがって、シグネチャは競合しており、同じクラスに実装することはできません。

2

あなた自身のインターフェイスを実装してみませんか?デイブ・コスタは、あなたがのLinkedHashMapを使用する必要があります言ったことに加えて

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ユーモアのセンス –

+0

非常に面白い:) "決してサポートされていない"インターフェースを使用するのは何ですか? – Donatello

1

。これはMapですが、要素の挿入順序が保持されます。

マップとしてvalues()メソッドが実装されているため、 new ArrayList(map.values())。get(0) をリスト機能と似ています。

map.get( "one") これは単なるマップ実装なので、 と言うこともできます。

関連する問題