
Baeldung Pro comes with both absolutely No-Ads as well as finally with Dark Mode, for a clean learning experience:
Once the early-adopter seats are all used, the price will go up and stay at $33/year.
Converting List to Map is a common task. In this tutorial, we’ll cover several ways to do this.
We’ll assume that each element of the List has an identifier that will be used as a key in the resulting Map.
First, we’ll model the element:
public class Animal {
private int id;
private String name;
// constructor/getters/setters
}
The id field is unique, so we can make it the key.
Let’s start converting with the traditional way.
Evidently, we can convert a List to a Map using core Java methods:
public Map<Integer, Animal> convertListBeforeJava8(List<Animal> list) {
Map<Integer, Animal> map = new HashMap<>();
for (Animal animal : list) {
map.put(animal.getId(), animal);
}
return map;
}
Now we test the conversion:
@Test
public void givenAList_whenConvertBeforeJava8_thenReturnMapWithTheSameElements() {
Map<Integer, Animal> map = convertListService
.convertListBeforeJava8(list);
assertThat(
map.values(),
containsInAnyOrder(list.toArray()));
}
Starting with Java 8, we can convert a List into a Map using streams and Collectors:
public Map<Integer, Animal> convertListAfterJava8(List<Animal> list) {
Map<Integer, Animal> map = list.stream()
.collect(Collectors.toMap(Animal::getId, Function.identity()));
return map;
}
Again, let’s make sure the conversion is done correctly:
@Test
public void givenAList_whenConvertAfterJava8_thenReturnMapWithTheSameElements() {
Map<Integer, Animal> map = convertListService.convertListAfterJava8(list);
assertThat(
map.values(),
containsInAnyOrder(list.toArray()));
}
Besides core Java, we can use third-party libraries for the conversion.
First, we need to add the following dependency to our pom.xml:
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>33.2.1-jre</version>
</dependency>
The latest version of this library can always be found here.
Second, let’s use Maps.uniqueIndex() method to convert a List into a Map:
public Map<Integer, Animal> convertListWithGuava(List<Animal> list) {
Map<Integer, Animal> map = Maps
.uniqueIndex(list, Animal::getId);
return map;
}
Finally, we test the conversion:
@Test
public void givenAList_whenConvertWithGuava_thenReturnMapWithTheSameElements() {
Map<Integer, Animal> map = convertListService
.convertListWithGuava(list);
assertThat(
map.values(),
containsInAnyOrder(list.toArray()));
}
We can also make a conversion with the Apache Commons library method.
First, let’s include Maven dependency:
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-collections4</artifactId>
<version>4.5.0-M2</version>
</dependency>
The latest version of this dependency is available here.
Second, we’ll make the conversion using MapUtils.populateMap():
public Map<Integer, Animal> convertListWithApacheCommons(List<Animal> list) {
Map<Integer, Animal> map = new HashMap<>();
MapUtils.populateMap(map, list, Animal::getId);
return map;
}
Finally, we can make sure it works as expected:
@Test
public void givenAList_whenConvertWithApacheCommons_thenReturnMapWithTheSameElements() {
Map<Integer, Animal> map = convertListService
.convertListWithApacheCommons(list);
assertThat(
map.values(),
containsInAnyOrder(list.toArray()));
}
Let’s check what happens if the id field isn’t unique.
First, we create a List of Animals with non-unique ids:
@Before
public void init() {
this.duplicatedIdList = new ArrayList<>();
Animal cat = new Animal(1, "Cat");
duplicatedIdList.add(cat);
Animal dog = new Animal(2, "Dog");
duplicatedIdList.add(dog);
Animal pig = new Animal(3, "Pig");
duplicatedIdList.add(pig);
Animal cow = new Animal(4, "Cow");
duplicatedIdList.add(cow);
Animal goat= new Animal(4, "Goat");
duplicatedIdList.add(goat);
}
As shown above, the cow and the goat have the same id.
Java Map‘s put() method is implemented so that the latest added value overwrites the previous one with the same key.
For this reason, the traditional conversion and Apache Commons MapUtils.populateMap() behave in the same way:
@Test
public void givenADupIdList_whenConvertBeforeJava8_thenReturnMapWithRewrittenElement() {
Map<Integer, Animal> map = convertListService
.convertListBeforeJava8(duplicatedIdList);
assertThat(map.values(), hasSize(4));
assertThat(map.values(), hasItem(duplicatedIdList.get(4)));
}
@Test
public void givenADupIdList_whenConvertWithApacheCommons_thenReturnMapWithRewrittenElement() {
Map<Integer, Animal> map = convertListService
.convertListWithApacheCommons(duplicatedIdList);
assertThat(map.values(), hasSize(4));
assertThat(map.values(), hasItem(duplicatedIdList.get(4)));
}
We can see that the goat overwrites the cow with the same id.
However, Collectors.toMap() and MapUtils.populateMap() throw IllegalStateException and IllegalArgumentException respectively:
@Test(expected = IllegalStateException.class)
public void givenADupIdList_whenConvertAfterJava8_thenException() {
convertListService.convertListAfterJava8(duplicatedIdList);
}
@Test(expected = IllegalArgumentException.class)
public void givenADupIdList_whenConvertWithGuava_thenException() {
convertListService.convertListWithGuava(duplicatedIdList);
}
In this quick article, we covered various ways of converting a List to a Map, giving examples with core Java as well as some popular third-party libraries.