2010-11-18 14 views
5

Me gustaría tener un objeto que implemente las interfaces Map y List en Java. La idea es similar al problema en esta pregunta: Java Ordered MapImplementa las interfaces de Mapa y Lista en Java?

Quiero añadir pares de nombre/valor a una lista y tener la lista de preservar la secuencia, sino también ser capaz de hacer búsquedas por nombre:

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

aquí está el problema: cuando se crea esta clase:

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

me sale un error de compilación:

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

Si no implemento las interfaces de Mapa y Lista, existen muchos métodos de recolección de Java que no están disponibles para usar en esta estructura de datos.

(También, la razón por la que la solución propuesta en Java Ordenado mapa anterior no funciona es que LinkedHashMap no tiene un método get (int). No se puede seleccionar las entradas de índice.)

+2

¿Está en contra de extender el 'LinkedHashMap', si no, ¿por qué no intenta agregar el método' get (int) 'a él? –

+0

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

+1

@ Adam ese enlace está roto, pero supongo que sabremos qué dice, solo de la URL;) – MatrixFrog

Respuesta

5

Como ha notado, no puede implementar List y Map en la misma clase. Pero para lo que necesita eso tampoco debería ser necesario. Lo que necesita es que se pueda acceder al data con una interfaz Map y List. Un poco como acceder a los datos Map como un conjunto en entrySet() o como una colección usando Map.values().

En resumen, lo que necesita son 2 vistas en los datos, una vista que implementa un List y otra vista que implementa Map.

Si hay una vista dominante (por ejemplo, Mapa), entonces podría darle a su implementación de mapa un método List getAsList() que presente los datos como una Lista, respaldada por los datos del Mapa.

EDITAR

La respuesta dada por Paulo Guedes debe servirle. Ya hay una implementación de mapas con sus requisitos. Mi respuesta es un poco más general, acerca de presentar los mismos datos usando múltiples interfaces incompatibles donde un Adaptador simple no es suficiente.

5

LinkedHashMap hace lo que necesitas

Tabla hash e implementación de lista enlazada de la interfaz de Mapa, con orden de iteración predecible. Esta implementación difiere de HashMap en que mantiene una lista doblemente enlazada que se ejecuta a través de todas sus entradas.

+0

No hay método 'get' para obtener elementos por el índice – Adam

+2

@Adam: luego extienda LinkedHashMap e implemente get (int index) usando el iterador. Incluso podría usar la matriz Backing Entry [] llamada 'table' (aunque usaría el iterador para robustez). – extraneon

1

Las interfaces Map y List contienen definiciones contradictorias de un método remove. No puede implementar ambos en una sola clase porque no puede anular la misma firma de método con una diferencia en el tipo de devolución solamente.

Me pregunto si usar List<Map.Entry<K,V>> satisfaría su necesidad.

5

Cabe señalar que el motivo del error es que Map contiene la definición para el remove método siguiente:

V remove(Object key) 

Mientras List define:

boolean remove(Object o) 

Y, en Java, los métodos no se pueden sobrecargar en función de su tipo de devolución, por lo que son firmas contradictorias y no pueden implementarse en la misma clase.

2

¿Por qué no implementa su propia interfaz?

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 por el sentido del humor –

+0

muy gracioso :) ¿De qué sirve usar una interfaz "nunca compatible"? – Donatello

1

Además de lo que Dave Costa dijo que se debe utilizar LinkedHashMap. Este es un mapa pero conserva el orden de inserción de los elementos.

Como mapa, implementa el método values ​​(), por lo que puede decir new ArrayList (map.values ​​()). Get (0) para imitar la funcionalidad de la lista.

pero también puede decir map.get ("one") porque es solo una implementación del mapa.

Cuestiones relacionadas