java新特性--03-1--Stream---Collectors工具类

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档

文章目录

  • 1.stream 收集
    • Collectors工具类
        • 注意区分 Collections工具类
    • 练习1:查找工资大于6000的员工,结果返回为一个List
    • 练习2:查找年龄小于40的员工,结果返回为一个set
    • 练习2:Collectors.toMap
      • (v1, v2) -> v2
  • 2.Collectors.groupingBy
      • 1. 基础分组功能 (3种写法一样效果)
        • 2.自定义键——字段映射![在这里插入图片描述](https://img-blog.csdnimg.cn/direct/9b6cc419aa2e49ba8e30b0986b30562b.png)
        • 3.自定义键——范围
      • 4.计数 求和 平均值
  • 3.Function.identity()
    • 1.JDK源码
    • 2.用法
      • 不适用场景
    • 3.案例
      • 案例1
      • 案例2
      • 对比 Collectors.groupingBy


1.stream 收集

在这里插入图片描述

Collectors工具类

在这里插入图片描述
在这里插入图片描述

注意区分 Collections工具类

在这里插入图片描述

练习1:查找工资大于6000的员工,结果返回为一个List

   @Testpublic void  test02() {List<Employee> list = new ArrayList<>();list.add(new Employee(1001, "马化腾", 34, 6000.38));list.add(new Employee(1002, "马云", 12, 9876.12));list.add(new Employee(1003, "刘强东", 33, 3000.82));list.add(new Employee(1004, "雷军", 26, 7657.37));list.add(new Employee(1005, "李彦宏", 65, 5555.32));list.add(new Employee(1006, "比尔盖茨", 42, 9500.43));list.add(new Employee(1007, "任正非", 26, 4333.32));list.add(new Employee(1008, "扎克伯格", 35, 2500.32));List<Employee> employeeList = list.stream().filter(e ->e.getSalary() > 6000).collect(Collectors.toList());employeeList.forEach(System.out::println);}

在这里插入图片描述

练习2:查找年龄小于40的员工,结果返回为一个set

 @Testpublic void test02() {List<Employee> list = new ArrayList<>();list.add(new Employee(1001, "马化腾", 34, 6000.38));list.add(new Employee(1002, "马云", 12, 9876.12));list.add(new Employee(1003, "刘强东", 33, 3000.82));list.add(new Employee(1004, "雷军", 26, 7657.37));list.add(new Employee(1005, "李彦宏", 65, 5555.32));list.add(new Employee(1006, "比尔盖茨", 42, 9500.43));list.add(new Employee(1007, "任正非", 26, 4333.32));list.add(new Employee(1008, "扎克伯格", 35, 2500.32));Set<Employee> employeeSet = list.stream().filter(employee ->employee.getAge() < 40).collect(Collectors.toSet());employeeSet.forEach(System.out::println);}

在这里插入图片描述

练习2:Collectors.toMap

在这里插入图片描述

package com.cy.month11;import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;public class Test05 {public static void main(String[] args) {List<Employee> list = Arrays.asList(new Employee("1","张三"),new Employee("2","李四"),new Employee("3","王五"));Map<String, String> map = list.stream().collect(Collectors.toMap(Employee::getId, Employee::getName));System.out.println(map.toString());}private static class Employee {String id;String name;public Employee(String id, String name) {this.id = id;this.name = name;}public String getId() {return id;}public void setId(String id) {this.id = id;}public String getName() {return name;}public void setName(String name) {this.name = name;}}
}

在这里插入图片描述
在这里插入图片描述

(v1, v2) -> v2

在这里插入图片描述

  • (v1, v2) -> v2 表示如果有相同的key,则使用后面的值覆盖key已经有的值。
  • 如果(v1, v2) ->v1, 则不覆盖,保留key已经有的值。

Map相同的key只能有一个。(注意:如果不指定覆盖策略,遇到相同key会抛异常)

案例

    public static void main(String[] args) {List<Person> personList =new ArrayList<>();personList.add(new Person("于问问","988"));personList.add(new Person("苗问问","988"));personList.add(new Person("李问问","777"));Map<String, String> personMap = personList.stream().collect(Collectors.toMap(Person::getCode, Person::getName));}

这样会不会有问题?答案是会有问题的。
Map的key值不能重复,现在于问问和苗问问的code号都是988

遇到这种情况转Map时就必须得有取舍了,苗问问和于问问只能留一个,那就留苗问问吧

        Map<String, String> personMap = personList.stream().collect(Collectors.toMap(Person::getCode, Person::getName, (v1, v2) -> v2));

2.Collectors.groupingBy

在这里插入图片描述
在这里插入图片描述

@Data
@AllArgsConstructor
public class Student {String name ;int  age;String clazz ;String course ;cint  score;}

1. 基础分组功能 (3种写法一样效果)

  • 说明:基础功能,分组并返回Map容器。将用户自定义的元素作为键,同时将键相同的元素存放在List中作为值。
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import java.util.stream.Stream;public class test {public static void main(String[] args) {List<Student> students = Stream.of(new Student("张三", 16, "高一1班", "语文", 88),new Student("李四", 17, "高一2班", "数学", 90),new Student("王五", 18, "高一3班", "外语", 100)).collect(Collectors.toList());// 方法1 :将不同课程的学生进行分类Map<String, List<Student>> groupByCourse = students.stream().collect(Collectors.groupingBy(Student::getCourse));System.out.println(groupByCourse);//  方法2 :上面的方法中容器类型和值类型都是默认指定的,容器类型为:HashMap,值类型为:ArrayListMap<String, List<Student>> groupByCourse1 = students.stream().collect(Collectors.groupingBy(Student::getCourse, Collectors.toList()));System.out.println(groupByCourse1);// 方法3 : 可以通过下面的方法自定义返回结果、值的类型Map<String, List<Student>> groupByCourse2 = students.stream().collect(Collectors.groupingBy(Student::getCourse, HashMap::new, Collectors.toList()));System.out.println(groupByCourse2);}}
{数学=[Student(name=李四, age=17, clazz=高一2, course=数学, score=90)], 语文=[Student(name=张三, age=16, clazz=高一1, course=语文, score=88)], 外语=[Student(name=王五, age=18, clazz=高一3, course=外语, score=100)]}
{数学=[Student(name=李四, age=17, clazz=高一2, course=数学, score=90)], 语文=[Student(name=张三, age=16, clazz=高一1, course=语文, score=88)], 外语=[Student(name=王五, age=18, clazz=高一3, course=外语, score=100)]}
{数学=[Student(name=李四, age=17, clazz=高一2, course=数学, score=90)], 语文=[Student(name=张三, age=16, clazz=高一1, course=语文, score=88)], 外语=[Student(name=王五, age=18, clazz=高一3, course=外语, score=100)]}
2.自定义键——字段映射在这里插入图片描述
package com.cy.demo;import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import java.util.stream.Stream;public class test {public static void main(String[] args) {List<Student> students = Stream.of(new Student("张三", 16, "高一1班", "语文", 88),new Student("李四", 17, "高一2班", "数学", 90),new Student("王五", 18, "高一3班", "外语", 100)).collect(Collectors.toList());// 字段映射 分组显示每个课程的学生信息Map<String, List<Student>> filedKey = students.stream().collect(Collectors.groupingBy(Student::getCourse));System.out.println(filedKey);// 组合字段 分组现实每个班不同课程的学生信息Map<String, List<Student>> combineFiledKey = students.stream().collect(Collectors.groupingBy(student -> student.getClazz() + "#" + student.getCourse()));System.out.println(combineFiledKey);}}
{数学=[Student(name=李四, age=17, clazz=高一2, course=数学, score=90)], 
语文=[Student(name=张三, age=16, clazz=高一1, course=语文, score=88)], 
外语=[Student(name=王五, age=18, clazz=高一3, course=外语, score=100)]}{高一2班#数学=[Student(name=李四, age=17, clazz=高一2, course=数学, score=90)],高一1班#语文=[Student(name=张三, age=16, clazz=高一1, course=语文, score=88)], 高一3班#外语=[Student(name=王五, age=18, clazz=高一3, course=外语, score=100)]}
3.自定义键——范围
package com.cy.demo;import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import java.util.stream.Stream;public class test {public static void main(String[] args) {List<Student> students = Stream.of(new Student("张三", 16, "高一1班", "语文", 75),new Student("李四", 17, "高一2班", "数学", 55),new Student("王五", 18, "高一3班", "外语", 100)).collect(Collectors.toList());// 根据两级范围 将学生划分及格不及格两类Map<Boolean, List<Student>> customRangeKey = students.stream().collect(Collectors.groupingBy(student -> student.getScore() > 60));System.out.println(customRangeKey);// 根据多级范围 根据学生成绩来评分Map<String, List<Student>> customMultiRangeKey = students.stream().collect(Collectors.groupingBy(student -> {if (student.getScore() < 60) {return "C";} else if (student.getScore() < 80) {return "B";}return "A";}));System.out.println(customMultiRangeKey);}}
{false=[Student(name=李四, age=17, clazz=高一2, course=数学, score=55)],true=[Student(name=张三, age=16, clazz=高一1, course=语文, score=75), Student(name=王五, age=18, clazz=高一3, course=外语, score=100)]}{A=[Student(name=王五, age=18, clazz=高一3, course=外语, score=100)], 
B=[Student(name=张三, age=16, clazz=高一1, course=语文, score=75)],
C=[Student(name=李四, age=17, clazz=高一2, course=数学, score=55)]}

4.计数 求和 平均值

package com.cy.demo;import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import java.util.stream.Stream;public class test {public static void main(String[] args) {List<Student> students = Stream.of(new Student("张三", 16, "高一1班", "语文", 75),new Student("李四", 17, "高一2班", "数学", 55),new Student("王五", 18, "高一3班", "外语", 100),new Student("赵六", 18, "高一1班", "语文", 88)).collect(Collectors.toList());// 计数Map<String, Long> groupCount = students.stream().collect(Collectors.groupingBy(Student::getCourse, Collectors.counting()));System.out.println(groupCount);// 求和Map<String, Integer> groupSum = students.stream().collect(Collectors.groupingBy(Student::getCourse, Collectors.summingInt(Student::getScore)));System.out.println(groupSum);// 增加平均值计算Map<String, Double> groupAverage = students.stream().collect(Collectors.groupingBy(Student::getCourse, Collectors.averagingInt(Student::getScore)));System.out.println(groupAverage);}}

在这里插入图片描述

3.Function.identity()

1.JDK源码

Java 8允许在接口中加入具体方法。接口中的具体方法有两种,default方法和static方法,identity()就是Function接口的一个静态方法。

  • Function.identity()返回一个输出跟输入一样的Lambda表达式对象,等价于形如t -> t形式的Lambda表达式。

在这里插入图片描述

2.用法

当我们使用 Stream 想要将集合的某一属性(例如手机号)作为 key,对象本身作为 value 时,就可以在 Collectors.toMap() 中配合使用 Function.identity()。

// 查询数据
List<UserInfo> list = userInfoMapper.getList();
// 获取 手机号-UserInfo 映射
Map<String, UserInfo> phoneNumberMap = list.stream().collect(Collectors.toMap(UserInfo::getPhoneNumber(), Function.identity(), (v1, v2) -> v1));

不适用场景

不适用于 mapToInt()、mapToLong()、mapToDouble() 等需要进行拆箱操作的场景。

public static void main(String[] args) {List<Integer> list = Arrays.asList(1, 2, 3);int[] array = list.stream().mapToInt(Function.identity()).toArray();System.out.println(array.length);
}

在这里插入图片描述

3.案例

案例1

    public static void main(String[] args) {Stream<String> stream = Stream.of("This", "is", "a", "test");Map<String, Integer> map = stream.collect(Collectors.toMap(Function.identity(), String::length));System.out.println(map);}

在这里插入图片描述
在这里插入图片描述

案例2

private static class Employee {String id;String  age;String name;public Employee(String id, String age, String name) {this.id = id;this.name = name;this.age = age;}public String getId() {return id;}public void setId(String id) {this.id = id;}public String getName() {return name;}public void setName(String name) {this.name = name;}public String getAge() {return age;}public void setAge(String age) {this.age = age;}@Overridepublic String toString() {return "Employee{" +"id='" + id + '\'' +", age='" + age + '\'' +", name='" + name + '\'' +'}';}}
    public static void main(String[] args) {List<Employee> list = Arrays.asList(new Employee("1","18","张三"),new Employee("2","25","李四"),new Employee("3","25","王五"));Map<String, String> map1 = list.stream().collect(Collectors.toMap(Employee::getId, Employee::getName,(v1, v2) -> v2) );System.out.println(map1.toString());Map<String, Employee> map2 = list.stream().collect(Collectors.toMap(Employee::getId, Function.identity()));System.out.println(map2.toString());}

在这里插入图片描述
在这里插入图片描述

对比 Collectors.groupingBy

  • Function.identity() 返回是对象本身 Map<String, Employee>
  • Collectors.groupingBy 返回的是 Map<String, List< Employee>>
    public static void main(String[] args) {List<Employee> list = Arrays.asList(new Employee("1","18","张三"),new Employee("2","25","李四"),new Employee("3","25","王五"));Map<String, String> map1 = list.stream().collect(Collectors.toMap(Employee::getId, Employee::getName,(v1, v2) -> v2) );System.out.println(map1.toString());Map<String, Employee> map2 = list.stream().collect(Collectors.toMap(Employee::getId, Function.identity()));System.out.println(map2.toString());Map<String, List<Employee>> map3 = list.stream().collect(Collectors.groupingBy(Employee::getId));System.out.println(map3.toString());Map<String, List<Employee>> map4 = list.stream().collect(Collectors.groupingBy(Employee::getAge));System.out.println(map4.toString());}

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/pingmian/22399.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【含项目亮点】小免鲜项目总结

【含项目亮点】小兔鲜项目总结 基础总结 vue3的优势 组合式API,更好的支持TS。速度提高,diff算法重写。按需引入,更好的treeshaking,体积小。数据式响应更优,使用js的proxy替代Object.defineProperty数据响应式系统,更灵活。 vue3使用的是vue-create脚手架工具,vue2使用…

【设计模式】结构型-组合模式

前言 在软件开发中&#xff0c;设计模式是一种被广泛应用的解决问题的方法论。其中&#xff0c;结构性设计模式是一类特别重要的模式&#xff0c;它们用于处理类或对象之间的组合关系&#xff0c;其中之一就是组合模式。组合模式允许客户端统一对待单个对象和对象的组合&#…

结构体(2),链表,共用体

链式数据结构 -- 链表 定义&#xff1a; struct Node { int data; //数据域 --存储要处理的数据 struct Node *next; //指针域&#xff0c;保存地址-- 指向下一个节点 }; //数据域指针域 //节点类型 struct Node n1; struct Node n2; struct Node n3; s1--&…

DeepSort整体流程梳理及匈牙利算法解析

文章目录 算法原理一、主要步骤二、算法流程:三、匈牙利算法:3.1 举例说明匈牙利匹配过程:3.2匈牙利算法中代价矩阵的计算(距离)卡尔曼滤波后面更新。 算法原理 DeepSort核心在于其对目标的外观特征和运动特征的联合使用,以及对目标匹配问题的优化处理。该算法通过融合目…

【前端技术】 ES6 介绍及常用语法说明

&#x1f604; 19年之后由于某些原因断更了三年&#xff0c;23年重新扬帆起航&#xff0c;推出更多优质博文&#xff0c;希望大家多多支持&#xff5e; &#x1f337; 古之立大事者&#xff0c;不惟有超世之才&#xff0c;亦必有坚忍不拔之志 &#x1f390; 个人CSND主页——Mi…

使用wheelnav.js构建酷炫的动态导航菜单

目录 前言 一、WheelNav是什么 1、项目地址 2、关于开源协议 3、相关目录介绍 二、如何使用wheelnav.js 1、新建html页面 2、设置style样式 3、创建展示元素实现动态导航 三、参数即方法介绍 1、参数列表 2、运行方法 3、实际成果 四、总结 前言 用户体验永远是一…

玩转盲盒潮流:从0到1搭建小程序平台

玩转盲盒潮流并搭建一个从0到1的小程序平台来创作内容是一个充满挑战但有趣的过程。以下是一个步骤指南&#xff0c;帮助你实现这一目标&#xff1a; 1. 市场调研与定位 了解盲盒市场&#xff1a;研究当前盲盒市场的趋势、消费者喜好和成功案例。确定目标用户&#xff1a;明确…

android-jni2

详细的jni调用说明&#xff1a;Android学习--JNI_android jni-CSDN博客 jclass clazz;index;LOGE("开始:%d", "begin");clazz (*env).FindClass("com/changan/incalleventservice/input/NativeAction");//找到对应的java文件jfieldID instanc…

docker-compose 部署rabbitmq 15672打不开

docker-compose 部署rabbitmq 15672打不开 如果docker-compose的rabbitmq镜像后缀不是-management如&#xff1a;3.7.4-management&#xff0c;则需要进入容器中手动启动插件 部署rabbitmq后需要启动插件的命令&#xff1a; rabbitmq-plugins enable rabbitmq_management 一…

软件质量保障——三、四

三、黑盒测试 1.黑盒测试概述 1.1 如何理解黑盒测试&#xff1f; 1.2 黑盒测试有什么特点&#xff1f; 1.3 如何实施黑盒测试&#xff1f; 2. 黑盒测试用例设计和生成方法&#xff08;这里还是要自己找题做&#xff09; 2.1 等价类划分法 步骤&#xff1a; 1.选择划分准…

解释JDBC的作用和连接数据库的步骤

JDBC&#xff08;Java Database Connectivity&#xff09;是Java编程语言中用来执行SQL语句的API。它的主要作用是为Java程序提供连接各种关系型数据库的能力&#xff0c;使得Java开发者能够编写出与数据库进行交互的应用程序。JDBC的作用具体体现在以下几个方面&#xff1a; 数…

在多支付渠道中这个设计模式无敌好用!

假设我们有一个电商平台&#xff0c;需要支持多种支付方式。 通过策略模式来实现&#xff0c;管理不同的支付方式&#xff0c;并根据需求快速添加新的支付方式。 定义支付策略接口及其实现类&#xff1a; // 支付策略接口 public interface PaymentStrategy { void pay(int …

SASS基础知识

什么是SASS 1. SASS与CSS的关系 SASS&#xff08;Syntactically Awesome Stylesheets&#xff09;是一种强大的CSS扩展语言&#xff0c;它允许开发者使用变量、嵌套规则、混合宏和更多功能&#xff0c;这些在纯CSS中是不可能做到的。SASS旨在简化CSS代码的维护&#xff0c;并…

C语言练习1

前言 从0开始记录我的学习历程&#xff0c;我会尽我所能&#xff0c;写出最最大白话的文章&#xff0c;希望能够帮到你&#xff0c;谢谢。 提示&#xff1a;文章作者为初学者&#xff0c;有问题请评论指正&#xff0c;感谢。 题目 1&#xff1a; 已有定义&#xff1a;char a…

BI平台概述

随着数字化浪潮的推进&#xff0c;企业对于数据驱动决策的需求日益增长。纷享销客作为一款领先的CRM平台&#xff0c;一直致力于帮助企业实现销售管理的高效与智能。纷享销客一体化BI智能分析平台作为CRM平台中的重要一环&#xff0c;旨在为企业提供更加全面、深入的数据分析能…

【EBS】通过SQL查找所有的定时请求

--查找所有定时请求。 --也可以登录系统&#xff0c;在系统管理员下查找特定请求&#xff0c;状态设置为Scheduled进行查询 SELECT DISTINCT USER_CONCURRENT_PROGRAM_NAME, B.RESUBMIT_INTERVAL, B.RESUBMIT_INTERVAL_UNIT_CODE FROM FND_CONCURRENT_PROGRAMS_TL A, FND_…

HBuilderX编写APP一、获取token

一、新建项目 二、从onenet获取key.js 1、下载之后的压缩包&#xff0c;解压2、关键就是找到key.js 3、将这个key.js复制到刚才的目录下面去 4、这个key.js文件就是生成token的代码 5、只要调用createCommonToken(params)这个函数&#xff0c;就可以实现生成token了 其中onload…

Vue Router源码分析

摘要&#xff1a;最近项目中遇到了点Vue Router的问题&#xff0c;发现有些只是没理清楚&#xff0c;再次复习了下Vue Router的源码&#xff0c;记录下... Vue-Router的能力十分强大&#xff0c;它支持hash、history、abstract 3种路由方式&#xff0c;提供了<router-link&g…

Java多线程核心工具类

1.Thread类&#xff1a;代表一个线程。你可以通过继承Thread类或实现Runnable接口来创建线程。 2.Executor框架&#xff1a;java.util.concurrent.Executors和java.util.concurrent.Executor接口提供了一种创建和管理线程池的方法&#xff0c;可以减少在创建和销毁线程上的开销…

【TB作品】msp430g2553单片机,OLED,PCF8591,ADC,DAC

硬件 OLED PCF8591 /** OLED* VCC GND* SCL接P2^0* SDA接P2^1*//** PCF8591* VCC GND* SCL接P1^4* SDA接P1^5*//* 板子上按键 P1.3 *//* 单片机ADC输入引脚 P1.1 *//* 说明&#xff1a;将PCF8591的DAC输出接到单片机ADC输入引脚 P1.1&#xff0c;单片机采集电压并显示 */功能…