Ведение заказа в HashMap

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

очевидная причина заключается в том, что HashMap не поддерживает порядок. Но мне нужно что-то сделать, чтобы это произошло. Я не могу изменить реализацию карты. Как я могу это сделать?

Рассмотрим данный код:

import java.util.*;
public class Dummy {

public static void main(String[] args) {
    System.out.println("Hello world !");
    List<String> list = new ArrayList<String>();
    list.add("A");list.add("B");list.add("C");
    list.add("D");list.add("E");list.add("F");

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

    for(int i=0;i<list.size();i=i+2)
        map.put(list.get(i),list.get(i+1));

    // Use map here to do some work

    List<String> l= new ArrayList<String>();
    for (Map.Entry e : map.entrySet()) {
        l.add((String) e.getKey());
        l.add((String) e.getValue());
    }
  }
}

Например: сначала, когда я распечатал элементы списка, он распечатал

A B C D E F 

Теперь, когда я печатаю элементы List l, он печатает

E F A B C D

Ответ 1

HashMap сам не поддерживает порядок вставки, но LinkedHashMap делает, поэтому используйте это вместо.

Как описано... HashMap:

Этот класс не дает никаких гарантий относительно порядка карты; в частности, он не гарантирует, что порядок будет оставаться постоянным с течением времени.

И LinkedHashMap:

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

Ответ 2

Используйте LinkedHashMap вместо HashMap для поддержания порядка.

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

Ответ 3

Почему вы не можете изменить реализацию Map (например, LinkedHashMap)?

Если есть логическое упорядочение, вы можете отсортировать список с пользовательским Comparator.

Ответ 4

HashMap не сохраняет порядок вставки

Реализация интерфейса карты на основе хэш-таблицы. Эта реализация обеспечивает все необязательные операции с картами и разрешает нулевые значения и нулевой ключ. (Класс HashMap примерно эквивалентен Hashtable, за исключением того, что он несинхронизирован и разрешает null.) Этот класс не дает никаких гарантий относительно порядка карты; в частности, он не гарантирует, что порядок будет оставаться постоянным с течением времени.

Используйте LinkedHashMap, если вы хотите сохранить порядок ключей

Ответ 5

Рассмотрите возможность сортировки ваших позиций. В случае строк уже есть естественный порядок; алфавитный. Вы можете создавать объекты, которые используют сортируемый класс, и поэтому вы можете использовать алгоритмы сортировки, чтобы поместить эти объекты в порядке, независимо от того, какой порядок вы получите из хеша!

Ответ 6

Это время для LinkedHashMap, это точно означает сохранение порядка вставки.

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

Ответ 7

Если вы действительно не можете переключиться на другую реализацию Map (LinkedHashMap, это именно то, что вы хотите), тогда единственная другая возможность - сохранить исходный List, и использовать его для создания нового List из Map.

public <T> List<T> listFromMapInOrder(final Map<T, T> map, final List<T> order) {
    List<T> result = new ArrayList<T>();
    for (T key : order) {
        if (map.containsKey(key)) {
            result.add(key);
            result.add(map.get(key));
        }
    }
    return result;
}

Но я бы реорганизовал код, пока не удалось перейти на LinkedHashMap.