java8新特性之toMap的用法——全网独一无二的通俗易懂的讲解

这篇具有很好参考价值的文章主要介绍了java8新特性之toMap的用法——全网独一无二的通俗易懂的讲解。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。


对于java8的新特性toMap方法,相信有很多人都在工作中用过,接下来就通俗易懂的讲解一下toMap吧

官网介绍

先来看看官网对于toMap方法的解释
toMap有个三个重载的方法,每一个重载方法的详解分别如下

(1)方法1:两个参数

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);
}

(2)方法2:三个参数

public static <T, K, U>
Collector<T, ?, Map<K,U>> toMap(Function<? super T, ? extends K> keyMapper,Function<? super T, ? extends U> valueMapper,
BinaryOperator mergeFunction)
{
return toMap(keyMapper, valueMapper, mergeFunction, HashMap::new);
}

(3)方法3:四个参数

public static <T, K, U, M extends Map<K, U>>
Collector<T, ?, M> toMap(Function<? super T, ? extends K> keyMapper,
Function<? super T, ? extends U> valueMapper,BinaryOperator mergeFunction,Supplier mapSupplier)

{
BiConsumer<M, T> accumulator
= (map, element) -> map.merge(keyMapper.apply(element),
valueMapper.apply(element), mergeFunction);
return new CollectorImpl<>(mapSupplier, accumulator, mapMerger(mergeFunction), CH_ID);
}

对于上述三个方法中每个参数做下解释
keyMapper:Key 的映射函数
valueMapper:Value 的映射函数
mergeFunction:当 Key 冲突时,调用的合并方法
mapSupplier:Map 构造器,在需要返回特定的 Map 时使用

补充一个重要的知识点,接下来讲解时会依照这个规则讲解

针对于Map集合,在执行put方法时
map.put(k1,v1);
map.put(k1,v2);
最终集合中保留下来的元素是[k1,v2]
总结:每次往Map集合put添加相同的key值时,后面的key对应的value会覆盖前面的那个key对应的value值。


官网看完了接下来开始进行针对性通俗易懂的解释

两个参数的toMap

(1)针对于两个参数的toMap方法,这里简写为toMap(key,value);
循环执行toMap方法的执行的效果相当于

Map map=new HashMap();
for(循环条件) {
if(map.containsKey(oldKey)){
throw new RuntimeException(“xxxxxx”);
}
map.put(key,value);
}
解析:在执行toMap方法在收集元素时,如果遇到了重复的key时,它无法解决这个冲突,即此时会报错。
即如果在循环执行toMap方法,并且往map集合插入重复的key时,默认会报错,具体原因可参考源码。

实践案例:
定义一个User(name=zs,age=23,idNumer=13245906)对象,它有三个属性,

1> Map<String,Integer> map=userList.stream().collect(Collectors.toMap(u->u.getName,u->getAge));
用于收集user类的name与age属性,并且将以key-value键值对的方式插入到map集合中
.
2>Map<String,User> map=userList.stream().collect(Collectors.toMap(u->u.getName,u->u));
用于收集user类的name与User类的对象,并且将key-value键值对的方式插入到map集合中
.
3>Map<String,User> map=userList.stream().collect(Collectors.toMap(u->u.getName,Function.identity()));
用于收集user类的name与User类的对象,并且将key-value键值对的方式插入到map集合中。

注意:这里的Function.identity()是对传入一个对象,并原封不动的返回的是个简法。
java8新特性之toMap的用法——全网独一无二的通俗易懂的讲解
总结:使用这种toMap方法在收集元素时,如果存在重复的Key值时,在收集的过程中会发生冲突,直接导致的后果就是报错。如果想要解决冲突,请参考第二种方法


三个参数的toMap

(2)针对于三个参数的toMap方法,这里简写为两种方式
方式1:toMap(key,value,(k1,k2)->k1);
方式2:toMap(key,value,(k1,k2)->k2);
这两种方式看上去没多大区别,但是意义上却大相径庭,来看看分解后的效果讲解吧

方式1:循环执行toMap方法的执行的效果相当于

Map map=new HashMap();
for(循环条件) {
if(!map.containsKey(oldKey)){
map.put(key,value);
}
}
总结:方式1中的toMap方法在收集元素时,如果遇到了重复的key时,它会放弃收集后面的那个key对应的元素。(k1,k2)->k1就表示k1==k2相同时,保留前面的k1对应的那个键值对,放弃k2对应的那个键值对。

方式2:循环执行toMap方法的执行的效果相当于

Map map=new HashMap();
for(循环条件) {
map.put(key,value);
}
总结:方式1中的toMap方法在收集元素时,如果遇到了重复的key时,它会放弃收集前面的那个key对应的元素。(k1,k2)->k2就表示k1==k2相同时,保留后面最新收集的k2对应的那个键值对,放弃以前收集过的k1对应的那个键值对。

实践案例:
定义一个User(name=zs,age=23,idNumer=13245906)对象,它有三个属性

方式1
Map<String,Integer> map=userList.stream().collect(Collectors.toMap(u->u.getName,u->u.getAge,(k1,k2)->k1));
用于收集user类的name与age属性,并且将以key-value键值对的方式插入到map集合中.
如果在收集过程中发现重名的name值,则保留原先集合中存在的那个key及其对应的value值。舍弃最新待收集的key及其对应的value
.
方式2
Map<String,Integer> map=userList.stream().collect(Collectors.toMap(u->u.getName,u->u.getAge,(k1,k2)->k2));
用于收集user类的name与age属性,并且将以key-value键值对的方式插入到map集合中.
如果在收集过程中发现重名的name值,则舍弃原先集合中存在的那个key及其对应的value值。保留最新待收集的key及其对应的value


四个参数的toMap

(3)针对于四个参数的toMap方法,这里简写为多种方式
方式1:toMap(key,value,(k1,k2)->k1,HashMap::New);
toMap(key,value,(k1,k2)->k2,HashMap::New);
方式2:toMap(key,value,(k1,k2)->k1,TreeMap::New);
toMap(key,value,(k1,k2)->k2,TreeMap::New);
可以对收集到TreeMap集合中的元素按照相应的排序规则进行排序
方式3:toMap(key,value,(k1,k2)->k1,LinkedHashMap::New);
toMap(key,value,(k1,k2)->k2,LinkedHashMap::New);
可以保证收集到LinkedHashMap集合中的元素依旧保持原来的顺序

实践举例:这三种方式其实没多大区别,我们拿其中一个方式举例

针对方式3的toMap(key,value,(k1,k2)->k2,LinkedHashMap::New); 你可以这样理解。
Map map=new LinkedHashMap();
for(循环条件) {
map.put(key,value);
}
解析:在执行toMap方法在收集元素时,创建一个LinkedHashMap集合,然后使用该集合来收集元素,其余的效果同toMap(key,value,(k1,k2)->k2);一样。

经过刚刚的举例讲解,其实也能大概理解这种方式的含义了,它就是在执行toMap方法时构建一个自定义的Map容器,然后循环执行toMap方法时往集合里收集元素,所以该系列方法同三个参数的toMap方法原理几乎一摸一样。

默认情况下,toMap(key,value)与toMap(key,value,(k1,k2)->k1);方法在收集元素时都是构建的一个HashMap容器,然后使用HashMap容器去存储元素,但是HashMap集合我们都知道它是无序的,且无法针对集合中的元素进行排序。所以如果你在工作中有需要针对集合元素进行排序的需求时请使用四个参数的toMap方法.构建一个LinkedHashMap集合可以保证收集的数据依旧保持原来的顺序

总结
(1)toMap(key,value),创建一个HashMap集合用于收集元素,当在收集时出现了重复的key值,它会直接报错,并且中断收集元素到HashMap集合

(2)toMap(key,value,(k1,k2)->k1)创建一个HashMap集合用于收集元素,当在收集时出现了重复的key值时,它会根据(k1,k2)->k1)或者(k1,k2)->k2)这两种规则解决key值重复的冲突并收集元素到HashMap集合

(3) toMap(key,value,(k1,k2)->k2,LinkedHashMap::New)
创建一个LinkedHashMap集合用于收集元素,当在收集时出现了重复的key值时,它会根据(k1,k2)->k1)或者(k1,k2)->k2)这两种规则解决key值重复的冲突并收集元素到LinkedHashMap集合。这种方式的最大好处是可以自定义一个Map集合用于收集元素。

深入理解

public static <T, K, U, M extends Map<K, U>>
Collector<T, ?, M> toMap(Function<? super T, ? extends K> keyMapper,
Function<? super T, ? extends U> valueMapper,
BinaryOperator mergeFunction,
Supplier mapSupplier)

keyMapper与valueMapper均是一个Function函数,而Function函数的特性是传入一个参数,返回一个参数,于是乎我们可以写
Function<? super T, ? extends K> keyMapper = t->k;
Function<? super T, ? extends U> valueMapper = t->u;
BinaryOperator mergeFunction = (o, n)->o 或者 (o, n)->n
Supplier mapSupplier = ()->m;

调用的时候可以这样写:toMap(keyMapper, valueMapper, mergeFunction, mapSupplier);文章来源地址https://www.toymoban.com/news/detail-477994.html

@Data
public class Student {
   //学号
    private  String no;  
    //姓名
    private  String name;	
}
@Data
public class Teacher{
    //教师号
    private  String no; 
    //姓名 
    private  String name; 
}

list.add(new Student("1001", "小A"));  
     list.add(new Student("1001", "小B"));//学号重复(下面特殊处理)
     list.add(new Student("1002", "小C"));
     list.add(new Student("1003", "小D"));

   //将list转map 【key为多个属性,value为1个属性】  
Map<String, String> map =
    list.stream().collect(Collectors.toMap( 
        obj -> {
          return obj.getNo() + "_" + obj.getName();
        },
        Student::getName,
        (key1 , key2) -> key1   //(map的键重复不会报错,下面已经处理)
));  

Map<String, Teacher> map = 
    list.stream().collect(Collectors.toMap(
        Student::getNo, 
        stu -> {
            Teacher teacher = new Teacher();
            teacher.setNo(stu.getNo());
            teacher.setName(stu.getName());
            return teacher;
        },  
        (key1 , key2) -> key1,LinkedList::New
));

到了这里,关于java8新特性之toMap的用法——全网独一无二的通俗易懂的讲解的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 篇一:单例模式:C++中的独一无二

    篇一: “单例模式:C++中的独一无二” 设计模式在软件开发中起到了至关重要的作用,其中单例模式是最为常用且基础的设计模式之一。单例模式确保一个类只有一个实例,并提供全局访问点,以保证系统中的某个对象只有唯一的存在。在C++中,单例模式经常被用于管理资

    2024年02月13日
    浏览(44)
  • 【Python】Python仓储管理系统(源码)【独一无二】

    👉博__主👈:米码收割机 👉技__能👈:C++/Python语言 👉公众号👈:测试开发自动化【获取源码+商业合作】 👉荣__誉👈:阿里云博客专家博主、51CTO技术博主 👉专__注👈:专注主流机器人、人工智能等相关领域的开发、测试技术。 使用面相对象设计方法设计一个仓储管理

    2024年02月05日
    浏览(63)
  • UUID算法:独一无二的标识符解决方案

    在分布式系统和大数据环境下,唯一标识符的生成和管理是一项关键任务。UUID(Universally Unique Identifier)算法应运而生,成为了解决重复数据和标识符冲突的有效工具。本文将探讨UUID算法的优势和劣势,分析其在分布式系统、大数据环境以及其他领域中的应用,同时给出Py

    2024年02月19日
    浏览(37)
  • (数组) 1207. 独一无二的出现次数 ——【Leetcode每日一题】

    难度:简单 给你一个整数数组 arr ,请你帮忙统计数组中每个数的出现次数。 如果每个数的出现次数都是独一无二的,就返回 true ;否则返回 false 。 示例 1: 输入:arr = [1,2,2,1,1,3] 输出:true 解释:在该数组中,1 出现了 3 次,2 出现了 2 次,3 只出现了 1 次。没有两个数的出

    2024年02月08日
    浏览(32)
  • 【python】python小游戏——开心消消乐(源码)【独一无二】

    👉博__主👈:米码收割机 👉技__能👈:C++/Python语言 👉公众号👈:测试开发自动化【获取源码+商业合作】 👉荣__誉👈:阿里云博客专家博主、51CTO技术博主 👉专__注👈:专注主流机器人、人工智能等相关领域的开发、测试技术。 基于 Pygame 的游戏程序,它实现了一个类

    2024年04月11日
    浏览(31)
  • 【python】python旅游网数据抓取分析(源码+论文)【独一无二】

    👉博__主👈:米码收割机 👉技__能👈:C++/Python语言 👉公众号👈:测试开发自动化【获取源码+商业合作】 👉荣__誉👈:阿里云博客专家博主、51CTO技术博主 👉专__注👈:专注主流机器人、人工智能等相关领域的开发、测试技术。 每个爬虫针对特定的目标网站(去哪儿网

    2024年02月04日
    浏览(44)
  • 【Python】python天气数据抓取与数据分析(源码+论文)【独一无二】

    👉博__主👈:米码收割机 👉技__能👈:C++/Python语言 👉公众号👈:测试开发自动化【获取源码+商业合作】 👉荣__誉👈:阿里云博客专家博主、51CTO技术博主 👉专__注👈:专注主流机器人、人工智能等相关领域的开发、测试技术。 本项目包括四个核心部分:数据爬取、数

    2024年02月05日
    浏览(66)
  • 【C++面向对象】C++餐厅点餐管理系统【独一无二】

    👉博__主👈:米码收割机 👉技__能👈:C++/Python语言 👉公众号👈:测试开发自动化 👉荣__誉👈:阿里云博客专家博主、51CTO技术博主 👉专__注👈:专注主流机器人、人工智能等相关领域的开发、测试技术。 使用c++编写一个餐厅点餐管理系统,主要功能如下: 客户点餐功

    2024年02月03日
    浏览(60)
  • 【python】当当书籍数据抓取分析与可视化(代码+报告)【独一无二】

    👉博__主👈:米码收割机 👉技__能👈:C++/Python语言 👉公众号👈:测试开发自动化【获取源码+商业合作】 👉荣__誉👈:阿里云博客专家博主、51CTO技术博主 👉专__注👈:专注主流机器人、人工智能等相关领域的开发、测试技术。 本项目旨在研究和分析当当网上的书籍信

    2024年02月04日
    浏览(43)
  • 个性化纹身设计,Midjourney带你探索独一无二的艺术之美

    hello,大家好,欢迎回来。 在当今社会,纹身已经变得非常常见。 在寻求与众不同的个性化纹身时,你是否曾经为了找不到独特的设计而苦恼? 现在,Midjourney将为你打开一扇全新的艺术之门,引领你探索纹身设计的无穷魅力。 我们深知每一个纹身都承载着个人的故事和情感

    2024年02月22日
    浏览(37)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包