問題描述
工作中遇到需要將某個List里面的實體類的兩個屬性對應起來,比如根據(jù)姓名找到年齡,就是將List里面的entity屬性解析之后放到Map里。
實體類:
public class Person {
private String name;
private Integer age;
...省略getter、setter
}
邏輯:
Person person = new Person("張三",20);
Person person1 = new Person("李四",20);
Person person2 = new Person("張三",20);
List<Person> list = new ArrayList<Person>(){{
add(person);
add(person1);
add(person2);
}};
Map<String, Integer> map = new HashMap<>();
//常規(guī)寫法
for (Person p : list) {
map.put(p.getName(), p.getAge());
}
System.out.println(map);
//stream 流寫法
Map<String, Integer> collect = list.stream().collect(Collectors.toMap(Person::getName, Person::getAge));
System.out.println(collect);
單純常規(guī)寫法肯定沒什么問題,就是后面的key會被覆蓋,但是stream流不行,會報錯。
Exception in thread "main" java.lang.IllegalStateException: Duplicate key 20
原因分析:
Collectors.toMap這個方法其實是有三個參數(shù)的,第一個是key,第二個是value,第三個是發(fā)生沖突的合并規(guī)則。
默認采用的就是沖突之后拋出異常的處理。
public static <T, K, U>
Collector<T, ?, Map<K,U>> toMap(Function<? super T, ? extends K> keyMapper,
Function<? super T, ? extends U> valueMapper) {
return toMap(keyMapper, valueMapper, throwingMerger(), HashMap::new);
}
解決方案:
只需要加上第三個參數(shù)即可
public static <T, K, U>
Collector<T, ?, Map<K,U>> toMap(Function<? super T, ? extends K> keyMapper,
Function<? super T, ? extends U> valueMapper,
BinaryOperator<U> mergeFunction) {
return toMap(keyMapper, valueMapper, mergeFunction, HashMap::new);
}
新代碼只需要更改第三個參數(shù)
即可,會跟常規(guī)寫法一個效果文章來源:http://www.zghlxwxcb.cn/news/detail-816262.html
Map<String, Integer> collect = list.stream().collect(Collectors.toMap(Person::getName, Person::getAge, (oldValue, newValue) -> newValue));
當然還可以采用Collectors.groupingBy(keyFunction)
的寫法,但是返回值會是Map<key, List<value>>
的形式。這就是新的業(yè)務場景了。
附上代碼:文章來源地址http://www.zghlxwxcb.cn/news/detail-816262.html
Map<String, List<Person>> collect1 = list.stream().collect(Collectors.groupingBy(Person::getName));
到了這里,關(guān)于java 8 stream toMap key的重復問題的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!