Code ví dụ Java 8 chuyển List sang Map
Trong bài này mình sẽ thực hiện ví dụ chuyển 1 List object sang dạng Map và sử lý các trường hợp trùng key khi cho vào map.
Chuyển List sang Map
Để chuyển từ list sang map ta sẽ tạo stream từ list và dùng method Collectors.toMap()
để tạo map từ stream đó.
Ví dụ chuyển 1 danh sách các customer sang dạng map:
package stackjava.com.demo; public class Customer { private int id; private String name; private String address; @Override public String toString() { return "Customer [id=" + id + ", name=" + name + ", address=" + address + "]"; } // getter - setter }
public static void main(String[] args) { List<Customer> customers = new ArrayList<>(); customers.add(new Customer(1, "name1", "address1")); customers.add(new Customer(2, "name2", "address1")); customers.add(new Customer(3, "name3", "address2")); customers.add(new Customer(4, "name4", "address2")); customers.add(new Customer(5, "name5", "address3")); customers.add(new Customer(6, "name6", "address3")); System.out.println("************* key = id, value = customer ************"); Map<Integer, Customer> map1 = customers.stream() .collect(Collectors.toMap(Customer::getId, Function.identity())); // or // Map<Integer, Customer> map1 = customers.stream().collect(Collectors.toMap(x -> x.getId(), x -> x)); map1.forEach((key, value) -> System.out.println("Key : " + key + " - Value : " + value)); System.out.println("************* key = id, value = name ************"); Map<Integer, String> map2 = customers.stream().collect(Collectors.toMap(Customer::getId, Customer::getName)); map2.forEach((key, value) -> System.out.println("Key : " + key + " - Value : " + value)); }
Kết quả:
************* key = id, value = customer ************ Key : 1 - Value : Customer [id=1, name=name1, address=address1] Key : 2 - Value : Customer [id=2, name=name2, address=address1] Key : 3 - Value : Customer [id=3, name=name3, address=address2] Key : 4 - Value : Customer [id=4, name=name4, address=address2] Key : 5 - Value : Customer [id=5, name=name5, address=address3] Key : 6 - Value : Customer [id=6, name=name6, address=address3] ************* key = id, value = name ************ Key : 1 - Value : name1 Key : 2 - Value : name2 Key : 3 - Value : name3 Key : 4 - Value : name4 Key : 5 - Value : name5 Key : 6 - Value : name6
Trường hợp key bị trùng
Ở ví dụ trên ta dùng id làm key nên không xảy ra tình trạng trùng key khi chuyển list sang map (vì id không trùng nhau)
Nếu ta dùng address làm key thì khi chuyển list sang map sẽ gặp vấn đề trùng key:
Ví dụ nếu ta chuyển sang map address-name như sau se bị lỗi:
Map<String, String> map2 = customers.stream().collect(Collectors.toMap(Customer::getAddress, Customer::getName));
Kết quả:
Exception in thread "main" java.lang.IllegalStateException: Duplicate key name1
Để giải quyết tình huống này ta sẽ có 1 bước chọn xem khi key bị trùng nhau thì ta sẽ lấy value nào:
Ví dụ khi duyệt, nếu gặp 1 đối tượng có key bị trùng mình sẽ thay value cũ bằng value mới:
public static void main(String[] args) { List<Customer> customers = new ArrayList<>(); customers.add(new Customer(1, "name1", "address1")); customers.add(new Customer(2, "name2", "address1")); customers.add(new Customer(3, "name3", "address2")); customers.add(new Customer(4, "name4", "address2")); customers.add(new Customer(5, "name5", "address3")); customers.add(new Customer(6, "name6", "address3")); System.out.println("************* key = address, value = customer ************"); Map<String, Customer> map = customers.stream() .collect(Collectors.toMap(Customer::getAddress, Function.identity(), (oldValue, newValue) -> newValue)); map.forEach((key, value) -> System.out.println("Key : " + key + " - Value : " + value)); }
Kết quả:
************* key = address, value = customer ************ Key : address3 - Value : Customer [id=6, name=name6, address=address3] Key : address2 - Value : Customer [id=4, name=name4, address=address2] Key : address1 - Value : Customer [id=2, name=name2, address=address1]
Trường hợp value là 1 list object
Vẫn là ví dụ trên, dùng address làm key, nhưng sẽ giữ tất cả các customer có cùng address làm value, tức là key là address còn value là 1 list customer:
public static void main(String[] args) { List<Customer> customers = new ArrayList<>(); customers.add(new Customer(1, "name1", "address1")); customers.add(new Customer(2, "name2", "address1")); customers.add(new Customer(3, "name3", "address2")); customers.add(new Customer(4, "name4", "address2")); customers.add(new Customer(5, "name5", "address3")); customers.add(new Customer(6, "name6", "address3")); System.out.println("************* key = address, value = list customer ************"); Map<String, List<Customer>> map = customers.stream().collect(Collectors.toMap(Customer::getAddress, p-> { List<Customer> list = new ArrayList<>(); list.add(p); return list; }, (oldValue, newValue) -> { newValue.addAll(oldValue); return newValue; })); map.forEach((key, value) -> { System.out.println("Key : " + key + " - Value : " + value); }); }
Kết quả:
************* key = address, value = list customer ************ Key : address3 - Value : [Customer [id=6, name=name6, address=address3], Customer [id=5, name=name5, address=address3]] Key : address2 - Value : [Customer [id=4, name=name4, address=address2], Customer [id=3, name=name3, address=address2]] Key : address1 - Value : [Customer [id=2, name=name2, address=address1], Customer [id=1, name=name1, address=address1]]
Code ví dụ Java 8 chuyển List sang Map stackjava.com
Okay, Done!
Download code ví dụ trên tại đây.
References: http://www.oracle.com/…/-new-2157071.html