827

How do I convert a Map<key,value> to a List<value>? Should I iterate over all map values and insert them into a list?

1
  • 1
    I think it's not a good model if one has to convert map into list. One should write the code in such manner that this situation doesn't arrise. Commented Dec 5, 2017 at 17:13

13 Answers 13

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

assuming:

Map<Key,Value> map;
Sign up to request clarification or add additional context in comments.

8 Comments

Thanks! I was assuming the cast from Collection to List would work.
I suspect the reason it doesn't work is because the collection returned by values() is dependent on the underlying Map; by making a copy constructor call instead, you allocate storage and copy the values into that storage, thus breaking the connection...
If we have LinkedHashMap - will the order leave the same?
@user2022068 yes, order should be preserved with LinkedHashMap.
@SheldonR. yes - the collections returned by keySet() and values() are generally shim objects that give a Set or Collection view of the underlying structure (keySet() returns a Set to emphasize no dupes). For values(), the returned object may be a List, but often won't be. Creating a real List, as you say, breaks the link which means you're no longer dependent on the original Map. Sometimes though, you only need a List because some API requires one - reinforcing the rule that a good API should require only the most abstract interfaces it can get away with...
|
145

The issue here is that Map has two values (a key and value), while a List only has one value (an element).

Therefore, the best that can be done is to either get a List of the keys or the values. (Unless we make a wrapper to hold on to the key/value pair).

Say we have a Map:

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

The keys as a List can be obtained by creating a new ArrayList from a Set returned by the Map.keySet method:

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

While the values as a List can be obtained creating a new ArrayList from a Collection returned by the Map.values method:

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

The result of getting the List of keys:

Apple
Another
Hello

The result of getting the List of values:

3.14
Element
World

3 Comments

It should be noted that the order of values returned by those methods is not defined and for HashMap and similar un-sorted Map implementations it will be effectively random.
Yes, you would have to know it is a LinkedHashMap or something of that sort. The problem with the original question is that the question is misstated, that is it needs editing. The question is not to convert a Map to a List, but rather how to get the values of the map as a List. The method values gives you a Collection, but not a list, and hence the need for a neat little trick.
I think you could add to your answer what @M0les says: That you would need to "go via" SortedMap somehow. Either start with a concrete SortedMap implementation (Such as TreeMap) or insert your input Map into a SortedMap before converting that to List
72

Using the Java 8 Streams API.

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

4 Comments

I prefer the accepted, constructor-based answer. Streams should be for simplifying code.
@Aaron Yes, for the task of getting a List of values from Map the constructor seems to be simplier. However if you are using Streams extensivly in a codebase it's better to stay consistent.
when i use this get an error if I am fetching huge amount of data ..thread is looping on java.util.stream.ReduceOps$3.makeSink(Unknown Source). If threads loop infinitely, CPU consumption will start to spike up. Looping threads stack trace are given below, examine it
I also like this code, but IntelliJ IDE suggests to change the code like this: java List<Value> values = new ArrayList<>(map.values());
30

map.entrySet() gives you a collection of Map.Entry objects containing both key and value. you can then transform this into any collection object you like, such as new ArrayList(map.entrySet());

Comments

26

a list of what ?

Assuming map is your instance of Map

  • map.values() will return a Collection containing all of the map's values.
  • map.keySet() will return a Set containing all of the map's keys.

Comments

15

I guess you want to convert the values contained in the Map to a list? Easiest is to call the values() method of the Map interface. This will return the Collection of value objects contained in the Map.

Note that this Collection is backed by the Map object and any changes to the Map object will reflect here. So if you want a separate copy not bound to your Map object, simply create a new List object like an ArrayList passing the value Collection as below.

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

Comments

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

we can have both key and value pair in list.Also can get key and value using Map.Entry by iterating over list.

Comments

6

If you want to ensure the values in the resultant List<Value> are in the key-ordering of the input Map<Key, Value>, you need to "go via" SortedMap somehow.

Either start with a concrete SortedMap implementation (Such as TreeMap) or insert your input Map into a SortedMap before converting that to List. e.g.:

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

Otherwise you'll get whatever native ordering the Map implementation provides, which can often be something other than the natural key ordering (Try Hashtable or ConcurrentHashMap, for variety).

Comments

5
// 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());    
}

Comments

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

Comments

2
public List<Object> convertMapToList(Map<Object, Object> map){
    return new ArrayList<>(map.values());
}

2 Comments

Why the unnecessary cast here?
The object change you used example: String , Integer etc.
1

Here's the generic method to get values from map.

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 Comment

You have to initialize ArrayList with the size of Map, if you have a map got like 1 Million records, good luck with having .add() dealing with resizing the array over and over again.
1

If you want an immutable copy of the values:

List<Value> list = List.copyOf(map.values())

3 Comments

Why You not mention the package of List.copyOf?
because it is the usual java.util.List?
What? but popup .class only java.util.List.class

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.