Класс Java, который реализует карту и сохраняет порядок вставки?

Я ищу класс в java, который имеет связь с ключом, но без использования хешей. Вот что я сейчас делаю:

  • Добавьте значения в Hashtable.
  • Получить итератор для Hashtable.entrySet().
  • Итерация через все значения и:
    • Получить тег Map.Entry для итератора.
    • Создайте объект типа Module (пользовательский класс) на основе значения.
    • Добавить класс в JPanel.
  • Показать панель.

Проблема заключается в том, что у меня нет контроля над порядком, в котором я возвращаю значения, поэтому я не могу отображать значения в заданном порядке (без жесткого кодирования порядка).

Я использовал бы ArrayList или Vector для этого, но позже в коде мне нужно захватить объект Module для данного ключа, который я не могу сделать с помощью ArrayList или Vector.

Кто-нибудь знает о свободном/открытом Java-классе, который будет делать это, или о способе получения значений из Hashtable на основе того, когда они были добавлены?

Спасибо!

Ответ 1

Я предлагаю LinkedHashMap или TreeMap. A LinkedHashMap хранит ключи в том порядке, в котором они были вставлены, в то время как TreeMap хранится отсортированным с помощью Comparator или естественного Comparable упорядочения элементов.

Поскольку для большинства элементов не нужно сортировать элементы, LinkedHashMap должен быть быстрее для большинства случаев; TreeMap имеет производительность O(log n) для containsKey, get, put и remove, в соответствии с Javadocs, а LinkedHashMap - O(1) для каждого.

Если ваш API, который ожидает только предсказуемый порядок сортировки, в отличие от определенного порядка сортировки, рассмотрите использование интерфейсов, реализуемых этими двумя классами, NavigableMap или SortedMap. Это позволит вам не утечка конкретных реализаций в ваш API и после этого перейти к любому из этих конкретных классов или к совершенно другой реализации.

Ответ 2

Если неизменяемая карта соответствует вашим потребностям, тогда есть библиотека, названная Guava (см. также вопросы guava)

Guava предоставляет ImmutableMap с надежным пользовательским порядком итерации. Этот ImmutableMap имеет производительность O (1) для containsKey, get. Очевидно, что put и remove не поддерживаются.

ImmutableMap объекты построены с использованием либо элегантных статических методов удобства of() и copyOf() или Builder.

Ответ 3

Вы можете поддерживать Map (для быстрого поиска) и List (для заказа), но LinkedHashMap может быть самым простым. Вы также можете попробовать SortedMap, например. TreeMap, которые имеют любой указанный вами порядок.

Ответ 4

Я не знаю, является ли это open source, но после небольшого поиска в Google я нашел эту реализацию Map с использованием ArrayList. Кажется, это pre-1.5 Java, поэтому вы можете обобщить его, что должно быть легко. Обратите внимание, что эта реализация имеет доступ O (N), но это не должно быть проблемой, если вы не добавите сотни виджетов в ваш JPanel, чего вы не должны в любом случае.

Ответ 5

Вы можете попробовать выполнить Linked Tree Map.

Ответ 6

LinkedHashMap вернет элементы в том порядке, в котором они были вставлены в карту, когда вы перебираете значения keySet(), entrySet() или values ​​() на карте.

Map<String, String> map = new LinkedHashMap<String, String>();

map.put("id", "1");
map.put("name", "rohan");
map.put("age", "26");

for (Map.Entry<String, String> entry : map.entrySet()) {
    System.out.println(entry.getKey() + " = " + entry.getValue());
}

Это будет печатать элементы в том порядке, в котором они были помещены в карту:

id = 1
name = rohan 
age = 26 

Ответ 7

Всякий раз, когда мне нужно поддерживать естественный порядок вещей, которые известны заранее, я использую EnumMap

ключи будут перечислениями, и вы можете вставить их в любом порядке, но когда вы будете итерации, он будет итерировать в порядке перечисления (естественный порядок).

Также при использовании EnumMap не должно быть никаких коллизий, которые могут быть более эффективными.

Я действительно считаю, что использование enumMap делает для чистого читаемого кода. Вот example

Ответ 8

Поместите свои значения на карту и используйте ключ, который обертывает объект модуля, который затем правильно реализует значения equals и hashCode.