Как преобразовать карту в список в Java?


675

Каков наилучший способ конвертировать Map<key,value>в List<value>? Просто переберите все значения и вставьте их в список или я что-то пропускаю?


1
Я думаю, что это не очень хорошая модель, если нужно конвертировать карту в список. Нужно писать код таким образом, чтобы такая ситуация не возникала.
Ошибки происходят

Ответы:


1299
List<Value> list = new ArrayList<Value>(map.values());

при условии:

Map<Key,Value> map;

7
Спасибо! Я предполагал , бросание от Collectionк Listбудет работать.
спрашивает

1
Я подозреваю, что причина этого не в том, что коллекция, возвращаемая values ​​(), зависит от базовой карты; сделав вместо этого вызов конструктора копирования, вы выделяете хранилище и копируете значения в это хранилище, тем самым разрывая соединение ...
Шелдон Р.

4
Если у нас есть LinkedHashMap - заказ останется прежним?

1
@ user2022068 да, порядок должен быть сохранен с LinkedHashMap.
СьюзенW

1
@SheldonR. yes - коллекции, возвращаемые keySet()и, values()как правило, являются объектами-оболочками, которые дают представление Set или Collection базовой структуры ( keySet()возвращает Set, чтобы подчеркнуть отсутствие дубликатов). Ибо values()возвращаемый объект может быть List, но часто не будет. Создание настоящего Списка, как вы говорите, нарушает ссылку, что означает, что вы больше не зависите от исходной Карты. Иногда, однако, вам нужен только List, потому что некоторые API требуют одного - усиливая правило, что хороший API должен требовать только самых абстрактных интерфейсов, с
которыми

137

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

Поэтому лучшее, что можно сделать, - это получить Listключи или значения. (Если только мы не создадим оболочку для пары ключ / значение).

Скажем, у нас есть Map:

Map<String, String> m = new HashMap<String, String>();
m.put("Hello", "World");
m.put("Apple", "3.14");
m.put("Another", "Element");

Ключи Listможно получить, создав новый ArrayListиз Setвозвращенного Map.keySetметодом:

List<String> list = new ArrayList<String>(m.keySet());

Тогда как значения Listможно получить, создав новый ArrayListиз Collectionвозвращенного Map.valuesметодом:

List<String> list = new ArrayList<String>(m.values());

Результат получения Listключей:

яблоко
Другая
Привет

Результат получения Listзначений:

3,14
Элемент
Мир

3
Следует отметить, что порядок значений, возвращаемых этими методами, не определен, и для HashMapаналогичных несортированных Mapреализаций он будет фактически случайным.
Йоахим Зауэр

1
Да, вы должны знать, что это LinkedHashMap или что-то в этом роде. Проблема с оригинальным вопросом состоит в том, что вопрос искажен, то есть требует редактирования. Вопрос не в том, чтобы преобразовать карту в список, а в том, как получить значения карты в виде списка. Значения метода дают вам коллекцию, но не список, и, следовательно, необходимость в аккуратной маленькой хитрости.
демонголем

Я думаю, что вы могли бы добавить к своему ответу то, что говорит @ M0les: что вам нужно как-то "пройти через" SortedMap. Либо начните с конкретной реализации SortedMap (например, TreeMap), либо вставьте входную карту в SortedMap перед преобразованием ее в List
Ignacio Rubio

41

Использование Java 8 Streams API.

List<Value> values = map.values().stream().collect(Collectors.toList());

8
Я предпочитаю принятый, основанный на конструкторе ответ. Потоки должны быть для упрощения кода.
Аарон,

1
@Aaron Да, для задачи получения списка значений из Map конструктор выглядит проще. Однако, если вы используете Streams экстенсивно в кодовой базе, лучше оставаться последовательным.
Матей Кормут,

1
когда я использую это, получаю ошибку, если я получаю огромное количество данных .. поток зацикливается на java.util.stream.ReduceOps $ 3.makeSink (Неизвестный источник). Если потоки бесконечно зацикливаются, загрузка процессора начнет расти. Трассировка стека циклических потоков приведена ниже, изучите ее
Ганеш Гири,

24

map.entrySet()дает вам коллекцию Map.Entryобъектов, содержащих как ключ, так и значение. затем вы можете преобразовать это в любой объект коллекции, который вам нравится, например new ArrayList(map.entrySet());


23

список чего?

Предположим, mapэто ваш примерMap

  • map.values()вернет Collectionсодержащий все значения карты.
  • map.keySet()вернет Setсодержащий все ключи карты.

14

Я предполагаю , что вы хотите , чтобы преобразовать значения , содержащиеся в Mapк list? Проще всего вызвать values()метод Mapинтерфейса. Это вернет Collectionобъекты значения, содержащиеся в Map.

Обратите внимание, что это Collectionподдерживается Mapобъектом, и любые изменения в Mapобъекте будут отражены здесь. Поэтому, если вы хотите, чтобы отдельная копия не была привязана к вашему Mapобъекту, просто создайте новый Listобъект, например, ArrayListпередав значение, Collectionкак показано ниже.

ArrayList<String> list = new ArrayList<String>(map.values());

6

Вы можете сделать это так

List<Value> list = new ArrayList<Value>(map.values());

1
ОП спросить о том, как преобразовать в список <значение>. Когда предоставите ответы, лучше включить хорошее описание с предлагаемым решением. На этот вопрос уже принят ответ.
HaveNoDisplayName

5

Если вы хотите убедиться, что значения в результате List<Value>находятся в порядке клавиш ввода Map<Key, Value>, вам нужно «пройти через»SortedMap .

Либо начните с конкретной SortedMapреализации (например, TreeMap), либо вставьте свой вход Mapв, SortedMapпрежде чем преобразовать его в List. например:

Map<Key,Value> map;
List<Value> list = new ArrayList<Value>( new TreeMap<Key Value>( map ));

В противном случае вы получите то, что Mapобеспечивает реализация в собственном порядке , что часто может быть чем-то отличным от упорядочения естественного ключа (Try Hashtableили ConcurrentHashMap, для разнообразия).


5
    Map<String, Integer> map = new HashMap<String, Integer>();
    map.put("java", 20);
    map.put("C++", 45);

    Set <Entry<String, Integer>> set = map.entrySet();

    List<Entry<String, Integer>> list = new ArrayList<Entry<String, Integer>>(set);

у нас может быть пара ключей и значений в списке. Также можно получить ключ и значение, используя Map.Entry, перебирая список.


4
// you can use this
List<Value> list = new ArrayList<Value>(map.values());

// or you may use 
List<Value> list = new ArrayList<Value>();
for (Map.Entry<String, String> entry : map.entrySet())
{
list.add(entry.getValue());    
}

1
"Map<String , String > map = new HapshMap<String , String>;
 map.add("one","java");
 map.add("two" ,"spring");
 Set<Entry<String,String>> set =  map.entrySet();
 List<Entry<String , String>> list = new ArrayList<Entry<String , String>>    (set);
 for(Entry<String , String> entry : list ) {
   System.out.println(entry.getKey());
   System.out.println(entry.getValue());
 } "

1

Вот общий метод для получения значений из карты.

public static <T> List<T> ValueListFromMap(HashMap<String, T> map) {
    List<T> thingList = new ArrayList<>();

    for (Map.Entry<String, T> entry : map.entrySet()) {
        thingList.add(entry.getValue());
    }

    return thingList;
}

1
HashMap<Integer, List<String>> map = new HashMap<>(); 
List<String> list = new ArrayList<String>();
list.add("Java");
list.add("Primefaces");
list.add("JSF");
map.put(1,list);
if(map != null){
    return new ArrayList<String>((Collection<? extends String>) map.values());
}
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.