STACKJAVA

Code ví dụ Java 8 chuyển List sang Map

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