Реализовать интерфейс Map и List в Java?

Я хотел бы иметь объект, который реализует интерфейсы Map и List в Java. Идея похожа на проблему в этом вопросе: Java Заказал Карту

Я хочу добавить пары имя / значение в список и список сохранить последовательность, но также иметь возможность делать поиск по имени:

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 Ordered Map выше, не работает, заключается в том, что LinkedHashMap не имеет метода get(int). Не удается выбрать записи по индексу.)

6 ответов


как вы заметили, вы не можете реализовать оба List и Map в том же классе. Но для того, что вам нужно, это также не должно быть необходимо. То, что вам нужно заключается в том, что data могут быть доступны как Map и List интерфейс. Немного похоже на доступ Map данные как набор в entrySet() или как коллекция с использованием карта.values ().

короче говоря, вам нужно 2 представления данных, одно представление, реализующее List и еще один вид реализация Map.

если есть одно доминирующее представление (например, карта), то вы можете дать своей реализации Карты метод List getAsList(), который представляет данные в виде списка, опираясь на данные карты.

редактировать

ответ, данный Пауло Гедес должен служить вам. Уже есть реализация карты с вашими требованиями. Мой ответ немного более общий, о представлении одних и тех же данных с использованием нескольких несовместимых интерфейсов, где простого адаптера недостаточно.


LinkedHashMap делает то, что вам нужно.

хэш-таблица и реализация связанного списка интерфейса карты с предсказуемым порядком итераций. Эта реализация отличается от HashMap тем, что она поддерживает двусвязный список, проходящий через все его записи.


следует отметить, что причиной ошибки является то, что Map содержит определение для следующих remove способ:

V remove(Object key)

пока List определение:

boolean remove(Object o) 

и в Java методы не могут быть перегружены на основе их возвращаемого типа, поэтому они являются конфликтующими сигнатурами и не могут быть реализованы в одном классе.


почему бы вам не реализовать свой собственный интерфейс?

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();

}


на Map и List интерфейсы содержат конфликтующие определения a remove метод. Вы не можете реализовать оба в одном классе, потому что вы не можете переопределить одну и ту же сигнатуру метода с разницей только в типе возврата.

интересно, если использовать List<Map.Entry<K,V>> будет удовлетворять ваши потребности.


в дополнение к тому, что сказал Дэйв Коста, вы должны использовать LinkedHashMap. Это карта, но она сохраняет порядок вставки элементов.

Как map он реализует метод values (), поэтому вы можете сказать новый ArrayList(карта.значения.))(get(0) чтобы имитировать функциональность списка.

но вы также можете сказать карта.get ("one") потому что это просто реализация карте.