1. 程式人生 > 其它 >java8 物件轉map時重複key Duplicate key xxxx

java8 物件轉map時重複key Duplicate key xxxx

我們在利用java8 Lambda 表示式將集合中物件的屬性轉成Map時就會出現 Duplicate key xxxx , 說白了也就是key 重複了!案例如下:

@Getter
@Setter
@AllArgsConstructor
public class Student{
private String className;
private String studentName;

public static void main(String[] args) {
List<Student> list = new ArrayList<>();
list.add(new Student("一年級二班", "小明"));
list.add(new Student("一年級二班", "小芳"));
list.add(new Student("一年級二班", "小華"));
list.add(new Student("一年級三班", "翠花"));
list.add(new Student("一年級三班", "香蘭"));
// 集合中物件屬性轉map
Map<String, String> map = list.stream().collect(Collectors.toMap(Student :: getClassName, Student :: getStudentName));
System.out.println(map);
}

}
此時將物件的 班級名稱為 key 學生名稱為 value,但執行時出現了多個相同的key ,此時編譯器就會丟擲 Duplicate key xxxx


解決方案如下:

我們需要使用toMap的另外一個過載的方法!

Collectors.toMap(keyMapper, valueMapper, mergeFunction)
前兩兩個引數都是與之前一樣 key 和 value得取值屬性, 第三個引數是當key 發生重複時處理的方法,註釋上的解釋如下:

一種合併函式,用於解決兩者之間的衝突與提供的相同鍵相關聯的值到{@link Map#merge(Object, Object, BiFunction)}
該合併函式有兩個引數,第一個引數為當前重複key 之前對應的值,第二個為當前重複key 現在資料的值。

1、重複時採用後面的value 覆蓋前面的value

Map<String, String> map = list.stream().collect(Collectors.toMap(Student :: getClassName, Student :: getStudentName,
(value1, value2 )->{
return value2;
}));
輸出:
{一年級三班=香蘭, 一年級二班=小華}
也可以簡寫成這樣:

Map<String, String> map = list.stream().collect(Collectors.toMap(Student :: getClassName, Student :: getStudentName,
(key1 , key2)-> key2 ));
2、重複時將之前的value 和現在的value拼接或相加起來;

Map<String, String> map = list.stream().collect(Collectors.toMap(Student :: getClassName, Student :: getStudentName,
(key1 , key2)-> key1 + "," + key2 ));

輸出:
{一年級三班=翠花,香蘭, 一年級二班=小明,小芳,小華}
3、將重複key的資料變成一個集合!

Map<String, List<String>> map = list.stream().collect(Collectors.toMap(Student :: getClassName,
// 此時的value 為集合,方便重複時操作
s -> {
List<String> studentNameList = new ArrayList<>();
studentNameList.add(s.getStudentName());
return studentNameList;
},
// 重複時將現在的值全部加入到之前的值內
(List<String> value1, List<String> value2) -> {
value1.addAll(value2);
return value1;
}
));

輸出:
{一年級三班=[翠花, 香蘭], 一年級二班=[小明, 小芳, 小華]}
總結:

這幾個辦法都是基於toMap過載方法第三個引數來實現的!至於哪個方法最好,我覺得應該取決於具體業務

原文連結:https://blog.csdn.net/qq_35170213/article/details/80654889