Java 8 – Convert List to Map
package com.mkyong.java8
public class Hosting {
private int Id;
private String name; private long websites;public Hosting(int id, String name, long websites) {
Id = id; this.name = name; this.websites = websites; }//getters, setters and toString()
}1. List to Map – Collectors.toMap()
package com.mkyong.java8import java.util.ArrayList;
import java.util.List;import java.util.Map;import java.util.stream.Collectors;public class TestListMap {
public static void main(String[] args) {
List<Hosting> list = new ArrayList<>();
list.add(new Hosting(1, "liquidweb.com", 80000)); list.add(new Hosting(2, "linode.com", 90000)); list.add(new Hosting(3, "digitalocean.com", 120000)); list.add(new Hosting(4, "aws.amazon.com", 200000)); list.add(new Hosting(5, "mkyong.com", 1));// key = id, value - websites
Map<Integer, String> result1 = list.stream().collect( Collectors.toMap(Hosting::getId, Hosting::getName));System.out.println("Result 1 : " + result1);
// key = name, value - websites
Map<String, Long> result2 = list.stream().collect( Collectors.toMap(Hosting::getName, Hosting::getWebsites));System.out.println("Result 2 : " + result2);
// Same with result1, just different syntax
// key = id, value = name Map<Integer, String> result3 = list.stream().collect( Collectors.toMap(x -> x.getId(), x -> x.getName()));System.out.println("Result 3 : " + result3);
}}Output
Result 1 : {1=liquidweb.com, 2=linode.com, 3=digitalocean.com, 4=aws.amazon.com, 5=mkyong.com}
Result 2 : {liquidweb.com=80000, mkyong.com=1, digitalocean.com=120000, aws.amazon.com=200000, linode.com=90000}Result 3 : {1=liquidweb.com, 2=linode.com, 3=digitalocean.com, 4=aws.amazon.com, 5=mkyong.com} 2. List to Map – Duplicated Key!package com.mkyong.java8;import java.util.ArrayList;
import java.util.List;import java.util.Map;import java.util.stream.Collectors;public class TestDuplicatedKey {
public static void main(String[] args) {
List<Hosting> list = new ArrayList<>();
list.add(new Hosting(1, "liquidweb.com", 80000)); list.add(new Hosting(2, "linode.com", 90000)); list.add(new Hosting(3, "digitalocean.com", 120000)); list.add(new Hosting(4, "aws.amazon.com", 200000)); list.add(new Hosting(5, "mkyong.com", 1)); list.add(new Hosting(6, "linode.com", 100000)); // new line// key = name, value - websites , but the key 'linode' is duplicated!?
Map<String, Long> result1 = list.stream().collect( Collectors.toMap(Hosting::getName, Hosting::getWebsites));System.out.println("Result 1 : " + result1);
}
}Output – The error message below is a bit misleading, it should show “linode” instead of the value of the key.
Exception in thread "main" java.lang.IllegalStateException: Duplicate key 90000
at java.util.stream.Collectors.lambda$throwingMerger$0(Collectors.java:133) at java.util.HashMap.merge(HashMap.java:1245) //...2.2 To solve the duplicated key issue above, pass in the third mergeFunction argument like this :
Map<String, Long> result1 = list.stream().collect(
Collectors.toMap(Hosting::getName, Hosting::getWebsites, (oldValue, newValue) -> oldValue ) );Output
Result 1 : {..., aws.amazon.com=200000, linode.com=90000}
CopyNote(oldValue, newValue) -> oldValue ==> If the key is duplicated, do you prefer oldKey or newKey?3.3 Try newValue
Map<String, Long> result1 = list.stream().collect(
Collectors.toMap(Hosting::getName, Hosting::getWebsites, (oldValue, newValue) -> newvalue ) );Output
Result 1 : {..., aws.amazon.com=200000, linode.com=100000}
3. List to Map – Sort & Collect
package com.mkyong.java8;import java.util.*;
import java.util.stream.Collectors;public class TestSortCollect {
public static void main(String[] args) {
List<Hosting> list = new ArrayList<>();
list.add(new Hosting(1, "liquidweb.com", 80000)); list.add(new Hosting(2, "linode.com", 90000)); list.add(new Hosting(3, "digitalocean.com", 120000)); list.add(new Hosting(4, "aws.amazon.com", 200000)); list.add(new Hosting(5, "mkyong.com", 1)); list.add(new Hosting(6, "linode.com", 100000));//example 1
Map result1 = list.stream() .sorted(Comparator.comparingLong(Hosting::getWebsites).reversed()) .collect( Collectors.toMap( Hosting::getName, Hosting::getWebsites, // key = name, value = websites (oldValue, newValue) -> oldValue, // if same key, take the old key LinkedHashMap::new // returns a LinkedHashMap, keep order ));System.out.println("Result 1 : " + result1);
}
}Result 1 : {aws.amazon.com=200000, digitalocean.com=120000, linode.com=100000, liquidweb.com=80000, mkyong.com=1}
http://www.mkyong.com/java8/java-8-convert-list-to-map/