JDK8之Stream流及Lambda表达式简介说明

戚薇 Java经验 发布时间:2023-06-01 09:19:03 阅读数:13410 1
下文笔者讲述Stream的常见方法简介说明,如下所示

Stream流简介

Stream流是对集合对象功能的增强
   它专注于对集合对象进行各种非常便利、高效的聚合操作
如:
   分组、过滤、去重等操作
     它就像SQL语句一样简单
   Stream流中可以使用Lambda表达式
     提高编程效率和程序可读性
   Stream流具有代码简洁和快速开发的优点

Stream中常见方法汇总

操作类型接口方法
中间操作 concat() distinct() filter() flatMap() limit()
map() peek() skip() sorted() parallel()
sequential() unordered()
结束操作 allMatch() anyMatch() collect() count() findAny()
findFirst() forEach() forEachOrdered()
max() min() noneMatch() reduce() toArray()

常见使用示例

0.数据准备:
    list<StudentVO> studentList=new ArrayList<>();
    studentList.add(new StudentVO("1","小张","1",8,null,"广东深圳"));
    studentList.add(new StudentVO("2","小韩","2",14,null,"广东深圳"));
    studentList.add(new StudentVO("3","小王","1",20,null,"广东东莞"));
    studentList.add(new StudentVO("4","小周","1",13,null,"广东湛江"));
    studentList.add(new StudentVO("4","小李","2",7,null,"广东珠海"));

1.中间操作:
  map()用法:
	//用法一:
	List<String> addressList=studentList.stream().map(StudentVO::getAddress).collect(Collectors.toList());
	System.out.println("map()用法一: "+addressList.toString());
	//用法二:
	List<Integer> ageList=studentList.stream().map(x ->x.getAge()).collect(Collectors.toList());
	System.out.println("map()用法二: "+ageList.toString());
	//用法三:
	List<StudentDO> newStudentList=studentList.stream().map(x ->{
		StudentDO studentDO = new StudentDO();
		studentDO.setId(x.getId());
		studentDO.setName(x.getName());
		studentDO.setSex(x.getSex());
		return studentDO;
	}).collect(Collectors.toList());
	System.out.println("map()用法三: "+newStudentList.toString());

sorted()用法:
	//自然排序:(StudentVO需要实现Comparable<E>接口,重写compareTo()方法)
	List<StudentVO> studentVOAscList=studentList.stream().sorted().collect(Collectors.toList());
	System.out.println("自然排序: "+studentVOAscList.toString());
	//自然序逆序:
	List<StudentVO> studentVODescList=studentList.stream().sorted(Comparator.reverseOrder()).collect(Collectors.toList());
	System.out.println("自然序逆序: "+studentVODescList.toString());
	//自定义升序:
	List<StudentVO> studentVOSortedAscList=studentList.stream().sorted(Comparator.comparing(StudentVO::getSex)).collect(Collectors.toList());
	System.out.println("自定义升序: "+studentVOSortedAscList.toString());
	//自定义降序:
	List<StudentVO> studentVOSortedDescList=studentList.stream().sorted(Comparator.comparing(StudentVO::getSex).reversed()).collect(Collectors.toList());
	System.out.println("自定义降序: "+studentVOSortedDescList.toString());

filter()(过滤)用法:
	List<StudentVO> studentVOFilterList1=studentList.stream().filter(obj ->"北京顺义".equals(obj.getAddress())).collect(Collectors.toList());
	System.out.println("北京顺义的学生: "+studentVOFilterList1.toString());
	List<StudentVO> studentVOFilterList2=studentList.stream().filter(obj ->obj.getAge()>=18).collect(Collectors.toList());
	System.out.println("成年的学生: "+studentVOFilterList2.toString());

distinct()(去重)用法:
        List<StudentVO> studentVODistinctList=studentList.stream().distinct().collect(Collectors.toList());

 limit()(截取)用法:
        List<StudentVO> studentVOLimitList=studentList.stream().limit(2).collect(Collectors.toList());

skip()(跳过)用法:skip(Long n)
        List<StudentVO> studentVOSkipList=studentList.stream().skip(2).collect(Collectors.toList());


2.结束操作: 

forEach()用法:
        studentList.stream().forEach(x ->x.setAddress(x.getName()+":"+x.getPhone()));

reduce()归约:
    流由一个个元素组成,归约就是将一个个元素“折叠”成一个值,如求和、求最值、求平均值都是归约操作。

	// 方式一:自定义Lambda表达式求和
	int age1 = studentList.stream().map(StudentVO::getAge).reduce(0, (x1,x2)->x1+x2);
	System.out.println("自定义Lambda表达式求和: "+age1);

	//方式二:使用Integer.sum函数求和
	int age2 = studentList.stream().map(StudentVO::getAge).reduce(0,Integer::sum);
	System.out.println("使用Integer.sum函数求和: "+age2);
	//注:Integer类还提供了min、max等一系列数值操作,当流中元素为数值类型时可以直接使用

	//方式三:使用数值流求和
	int age3 = studentList.stream().mapToInt(StudentVO::getAge).sum();
	System.out.println("使用数值流求和: "+age3);
	//注:
	// 将普通流转换成数值流的方法:mapToInt、mapToDouble、mapToLong
	// 每种数值流都提供了数值计算函数,如max、min、sum等

collect()收集器:
    收集器是对流经过筛选、映射、去重等中间操作进行后的整理,以不同的形式展现

	//计数:
	long count1 = studentList.stream().collect(Collectors.counting());
	long count2= studentList.stream().count();
	long count3= studentList.size();
	System.out.println("计数:"+"count1: "+count1+" count2: "+count2+" count3: "+count3);

	//最值:
	//例1:年龄最大的学生
	Optional<StudentVO> oldStudent =studentList.stream().collect(Collectors.maxBy(Comparator.comparingInt(StudentVO::getAge)));
	//例2:年龄最小的学生
	Optional<StudentVO> youngStudent =studentList.stream().collect(Collectors.minBy(Comparator.comparingInt(StudentVO::getAge)));
	System.out.println("年龄最大的学生: "+oldStudent.toString()+" 年龄最小的学生: "+youngStudent.toString());

	//求和:
	//例:计算所有学生年龄总和
	int sum = studentList.stream().collect(Collectors.summingInt(StudentVO::getAge));
	System.out.println("所有学生年龄总和: "+sum);
	//注:Java8提供了summingInt、summingLong、summingDouble

	//平均值:
	//例:计算所有学生的年龄平均值
	double avg  = studentList.stream().collect(Collectors.averagingInt(StudentVO::getAge));
	System.out.println("所有学生的年龄平均值: "+avg);
	//注:计算平均值时,不论计算对象是int、long、double,计算结果一定都是double

	//一次性计算所有归约操作:
	//Collectors.summarizingInt函数能一次性将最值、均值、总和、元素个数全部计算出来,并存储在对象IntSummaryStatistics中
	IntSummaryStatistics collectList = studentList.stream().collect(Collectors.summarizingInt(StudentVO::getAge));
	collectList.getCount();
	collectList.getMin();
	collectList.getMax();
	collectList.getSum();
	collectList.getAverage();
	System.out.println("一次性计算所有归约操作: "+collectList.toString());
 
	//连接字符串:
	//例:指定分隔符,连接姓名字符串
	String names = studentList.stream().map(StudentVO::getName).collect(Collectors.joining(", "));
	System.out.println("指定分隔符,连接姓名字符串: "+names);

	//一般性的归约操作(自定义一个归约操作):以后细研究,先学会基本使用
	//自定义归约操作,需要使用Collectors.reducing函数,该函数接收三个参数:
	//第一个参数为归约的初始值、第二个参数为归约操作进行的字段、第三个参数为归约操作的过程
	//例:计算所有学生年龄总和
	Integer sumAge = studentList.stream().collect(Collectors.reducing(0, StudentVO::getAge, (i, j) -> i + j));
	System.out.println("所有学生年龄总: "+sumAge);

	//#分组:
	//将流中的元素按照指定类别进行划分,类似于SQL语句中的GROUPBY。
	//一级分组:
	//例:将所有学生分为小学、初中、高中、大学
	//注:返回Map<String,List<StudentVO>>类型
	Map<String,List<StudentVO>> result1 = studentList.stream()
			.collect(Collectors.groupingBy((studentVO)->{
				if(studentVO.getAge()>=7&&studentVO.getAge()<12){
					return "小学";
				} else if(studentVO.getAge()>=12&&studentVO.getAge()<15){
					return "初中";
				}else if(studentVO.getAge()>=15&&studentVO.getAge()<18){
					return "高中";
				}else if(studentVO.getAge()>=18&&studentVO.getAge()<22){
					return "大学";
				}
				return "其他";
			}));
	System.out.println("一级分组: "+result1.toString());

	//二级分组:
	//例:将所有学生分为小学、初中、高中、大学,并且按男女分组
	//注:返回Map<String, Map<String, List<StudentVO>>>类型
	Map<String, Map<String, List<StudentVO>>> result2 = studentList.stream()
			.collect(Collectors.groupingBy((studentVO) -> {
						if (studentVO.getAge() >= 7 && studentVO.getAge() < 12) {
							return "小学";
						} else if (studentVO.getAge() >= 12 && studentVO.getAge() < 15) {
							return "初中";
						} else if (studentVO.getAge() >= 15 && studentVO.getAge() < 18) {
							return "高中";
						} else if (studentVO.getAge() >= 18 && studentVO.getAge() < 22) {
							return "大学";
						}
						return "其他";
					}, Collectors.groupingBy(x->{
						if(x.getSex().equals("1")){
							return "男";
						}
						return "女";
					})
			));

	System.out.println("二级分组: "+result2.toString());

3.常用方法:

List转Map:
       Map<String, Object> map = list.stream().collect(Collectors.toMap(Student::getId, Student));
 List降序排列:
 
       List<Student> bjProcessTaskList = list.stream().
               sorted(Comparator.comparing(Student::getCreateTime).reversed()).collect(Collectors.toList());
List转String:
       String names = studentList.stream().map(StudentVO::getName).collect(Collectors.joining(", "));
      
Map遍历: 
HashMap<Integer, Integer> map = new HashMap<Integer, Integer>();
map.forEach((key, value)->{
           System.out.println("key:"+ key);
           System.out.println("value:"+ value);
           });
分组求和(2020-08-21):  
--IntSummaryStatistics集合,包含了max,min,sum,count
Map<String, IntSummaryStatistics> collect = list.stream().collect(Collectors.groupingBy(StudentVO::getName, Collectors.summarizingInt(StudentVO::getGrade)));
--分组求和
Map<String, int> collect = list.stream().collect(Collectors.groupingBy(StudentVO::getName, Collectors.summingInt(StudentVO::getGrade)));
 排序处理空指针(2021-05-07):  
Comparator.nullsLast(Long::compareTo)
  排序多个字段比较(2021-05-07):  
Comparator.comparing(XXX::getOrderId).reversed().thenComparing(XXX::getTaskId, Comparator.nullsLast(Long::compareTo)))

Lambda表达式

1.基本语法:
() -> expression
或
(parameters) -> expression
或
parameters -> expression
或
() ->{ statements;}
或
(parameters) ->{ statements;}
或
parameters ->{ statements;}
2.双冒号::的用法:
类名::方法名 
注:此处没有()
例:
Lambda表达式: person -> person.getAge();
使用双冒号: Person::getAge
表达式:new HashMap<>()
使用双冒号:HsahMap :: new
版权声明

本文仅代表作者观点,不代表本站立场。
本文系作者授权发表,未经许可,不得转载。

本文链接: https://www.Java265.com/JavaJingYan/202306/16855823746673.html

最近发表

热门文章

好文推荐

Java265.com

https://www.java265.com

站长统计|粤ICP备14097017号-3

Powered By Java265.com信息维护小组

使用手机扫描二维码

关注我们看更多资讯

java爱好者