第四章 函数式编程(Lambda表达式Stream流)
一、Lambda表达式
特点:是匿名函数 2是可传递
匿名函数:需要一个函数,但又不想命名一个函数的场景下使用lambda表达式,使用lambda表达式时函数内容应该简单
可传递:将lambda表达式传递给其他的函数,它当做参数,lambda作为一种更紧凑的代码风格,使java语言表达能力增强
语法:
Lambda表达式在java语言中引入一个新的语法元素和操作符,这个操作符为“->",该操作符被称为Lambda操作符或箭头操作符,它将Lambda分为两个部分:
左侧:指定了Lambda表达式所需要的所有参数:
右侧:指定了Lambda体,即Lambda表达式所要执行的功能。
常见语法格式:
有参:lambda表达式的基本格式为(x1,x2)->{表达式}
参数类型可以省略,两边的括号不能省略
如果表达式只有一行,那么表达式两边的花括号可以省略
如果只有一个参数,参数的括号可以省略
无参:无参时,参数的括号不能省略,参数类型可以省略
基本格式为()->{表达式}
示例:
语法格式一:无参,无返回值,Lambda体只需要一条语句:Runnable r=() ->System.out.println("hello lambda“);
语法格式二:Lambda需要一个参数:Consumer<String> con =(x) ->System.out.println(x);
语法格式三:Lambda只需要一个参数时,参数的小括号可以省略:Consumer<String> con=x -> System.out.println(x);
语法格式四:Lambda需要两个参数,并且有返回值:Comparator<Integer> com=(x,y) ->{System.out.println("函数式接口“);return Integer.compare(x,y);}
语法格式五:当Lambda体只有一条语句是,return与大括号可以省略:Comparator<Integer> com =(x,y)->Integer.compare(x,y);
二、Stream 流使用
Stream创建方法:
Stream stream= Stream.empty(); //创建空的Stream对象:
List<String> list=Arrays.asList(‘a’,’b’,’c’); //通过集合类中的stream或者parallelStream方法创建:
Stream listStream=list.stream();
Stream paralelListStream=list.parallelStream();
Stream s = Stream.of(“a”,”b”,”c”); //通过Stream的of方法创建:
Stream常用方法:
准备数据
Person p1 = new Person("1","张三","123",18,new BigDecimal(61.5));
Person p2 = new Person("2","李四","123",20,new BigDecimal(81.5));
Person p3 = new Person("3","王五","123",20,new BigDecimal(34.5));
Person p4 = new Person("4","赵六","123",17,new BigDecimal(34.5));
Person p5 = new Person("5","赵六","123",18,new BigDecimal(54.4));List<Person> list = new ArrayList<>();
list.add(p1); list.add(p2); list.add(p3); list.add(p4); list.add(p5);
Stream<String> stream = Stream.of("T1", "T2", "T3", "T1", "T4", "5");
两类:中间操作,终端操作 || 惰性求值,及早求值
filter :对stream中元素进行过滤
distinct :去重
sorted :排序
limit :限制个数:获得前几个
skip :限制个数:去掉前几个
map :元素一对一转换
close :关闭stream
1. filter :元素过滤:
list.stream().filter(person -> person.getAge() >= 18) .collect(Collectors.toList());
2 distinct 去重:
list.stream().filter(st -> st.contains("T")).distlist.inct().collect(Collectors.toList());
3 sorted 排序:
list.stream().sorted(Comparator.comparing(Person::getAge).reversed()).collect(Collectors.toList());
sorted 排序 有null值:
list.stream().sorted(Comparator.comparing(Person::getGrade,Comparator.nullsFirst(BigDecimal::compareTo)).reversed()).collect(Collectors.toList());
4.limit :类似sql 里 limit ,返回包含前n个元素的流
list.stream().sorted(Comparator.comparing(Person::getAge).reversed()).limit(3).collect(Collectors.toList());
5.skip:skip操作与limit相反,是跳过前n个元素,排序在2个之后的:
list.stream().sorted(Comparator.comparing(Person::getAge).reversed()).skip(3).collect(Collectors.toList());
6.map() 元素1对1 转换:
List<String> list5 = Stream.of("a","b","C").map(string->string.toUpperCase()).collect(Collectors.toList());
List<String> list6 = list.stream().map(Person::getUsername).collect(Collectors.toList());
终端操作:
reduce :规约,对数据进行操作,返回一个结果
collect :根据参数做操作
anyMatch :只要有一个满足返回true,否则false
allMatch :全部满足返回true,否则false
noneMatch :全部不满足返回true,否则false
forEach :对所有对象进行迭代处理,无返回值
iterator :返回Stream中所有对象的迭代器
toArray :返回元素数组
count :元素数量
max :最大元素
min :最小元素
findFirst :返回第一个对象
findAny :返回任意一个对象
reduce()规约:对经过参数化操作后的集合进行进一步的运算,可用对集合实施归约操作
// BigDecimal类型:
BigDecimal big1 = list.stream().map(p -> p.getGrade()).reduce(BigDecimal::add).get();
BigDecimal big2 = list.stream().filter(p->p.getGrade()!=null).map(Person::getGrade).reduce(BigDecimal.ZERO,BigDecimal::add);
// int
int i1 = list.stream().map(p -> p.getAge()).reduce(0,(a,b)->a+b);
int i2 = list.stream().map(Person::getAge).reduce(0,Integer::sum);
collect收集:
// collect(toList())方法由Stream里的值生成一个列表,是一个及早求值操作,可以理解为由Stream向Collection的转换
list.stream().filter(p->p.getAge()>=18).collect(Collectors.toList());
list转换为map:
Map<String, Person> collect = list.stream().collect(Collectors.toMap(Person::getId, p -> p));//使用Collectors.toMap()时 key 不能重复://解决办法:toMap()重载方法:
Map<String, Person> collect1 = list.stream().collect(Collectors.toMap(Person::getUsername, Function.identity(),(k1,k2)->k2));
分组:Collectors.groupingBy
Map<Integer, List<Person>> collect2 = list.stream().collect(Collectors.groupingBy(Person::getAge));
anyMatch allMatch noneMatch (筛选判断)
Stream.of("1", "2", "3", "4", "5").anyMatch(p -> p.equals("7")); //有一个满足为true
Stream.of("1", "2", "3", "4", "5").allMatch(p -> "6".compareTo(p)>0); //全部满足为true
Stream.of("1", "2", "3", "4", "5").noneMatch(p -> "6".compareTo(p) < 0);//全部不满足为true
String ids = "1,2,3,4,5";
List<Object> listIds = Arrays.asList(ids.split(",")).stream().collect(Collectors.toList());
boolean result = listIds.stream().anyMatch(p -> p.equals("2"));
System.out.println(result);
forEach:
list.stream().filter(p -> p.getAge() > 20).forEach(System.out::println);
list.stream().filter(p -> p.getAge() > 20).forEach(person -> System.out.println(person.getUsername()));
count:
long count = list.stream().count();
toArray:
Object[] objects = list.stream().toArray();
Collectors 说明:Collectors是java.util.stream.Collectors类,提供了对流的操作:分组,排序(支持多字段排序),最大值,最小值,平均值。即数据可以在数据库中完成的操作,在Collectors也可以
Collectors.groupingBy(); //分组
Collectors.toList() //流转换
Collectors.toMap()
三、方法引用
方法引用用来替换函数式接口,使用方法引用可以是代码更加简洁
使用条件:方法的参数和返回值类型与函数式接口中抽象方法的参数和返回值类型一致
使用方法:方法引用主要有如下三种使用情况:
类::实例方法
类::静态方法
对象::实例方法
其中后两种情况等同于提供方法参数的lambda表达式
例如:System.out::println等同于(x) ->System.out.println(x) Math::pow 等同于(x,y) ->Math.pow(x,y)
第一种,第一个参数会成为执行方法的对象,String::compareToIgncCase等同于(x,y)->x.compareToIgnoreCase(y)
此外,方法引用还可以使用this::methodName及super::methodName表示该对象方法或者父类对象的方法
第四章 函数式编程(Lambda表达式Stream流)相关推荐
- 函数式编程 lambda表达式
函数式编程 lambda表达式 从JDK1.8之后为了简化程序的开发,专门提供了lambda表达式的支持,可以简化编程中接口的复杂操作: 范例: 观察以下传统开发中的问题 public interfa ...
- 【Java】函数式编程学习笔记——Stream流
学习视频:https://www.bilibili.com/video/BV1Gh41187uR?p=1 (1)[Java]函数式编程学习笔记--Lambda表达式 (2)[Java]函数式编程学习笔 ...
- 【Java10】lambda表达式(函数式编程),Stream流,File类,字节/字符流,乱码,缓冲/转换/序列化/打印流,Properties
文章目录 1.lambda表达式标准语法:()->{} 2.lambda表达式简略语法:可推导即可省略 3.lambda表达式原理:lambda效率比匿名内部类高 4.两个函数式接口:Consu ...
- Java8函数式编程(Lambda表达式,Stream流,Optional)
目录 一.函数式编程思想 二.lambda表达式 1.概念 2.Lambda表达式对接口的要求 编辑编辑编辑 3.Lambda表达式的语法 4.函数引用 4.1引用一个静态方法 4.2引用一个非 ...
- 函数式编程[Lambda 表达式,Optional,Stream流]从入门到精通(一)
文章目录 函数式编程.stream流 1.概述 1.1 学习目的 1.2 函数式编程思想 2.lambda表达式 2.1 概述 2.2 省略规则 3. stream流 3.1 概述 3.2 功能 3. ...
- java函数式编程例子_java函数式编程Lambda表达式的示例(一)
函数式编程是时下比较流行的编程方式了,很多新兴的编程语言都对函数式编程有了比较好的支持,她有别于传统的命令式编程,可以将函数(执行代码的过程)作为参数进行传递.JAVA也意识到了函数式编程的重要性,在 ...
- JDK1.8新特性之Lambda表达式+Stream流+函数式接口
一.Lambda表达式 Lambda表达式,是JDK1.8引入的一种语法,这种语法可以对匿名内部类的写法,进行简写. 1.快速入门 package org.westos.demo2;import ja ...
- 【怎样写代码】函数式编程 -- Lambda表达式(四):Lambda表达式与Expression树
如果喜欢这里的内容,你能够给我最大的帮助就是转发,告诉你的朋友,鼓励他们一起来学习. If you like the content here, you can give me the greates ...
- 【怎样写代码】函数式编程 -- Lambda表达式(三):LINQ初步
如果喜欢这里的内容,你能够给我最大的帮助就是转发,告诉你的朋友,鼓励他们一起来学习. If you like the content here, you can give me the greates ...
最新文章
- 印度首富要免费向全国提供4G网络3个月
- python反转列表的三种方式
- WebSnapshotsHelper(HTML转换为图片)
- T-SQL查询-逻辑查询处理
- linux和android学习,android学习笔记
- java synchronized静态同步方法与非静态同步方法,同步语句块
- magento effects.js jquery.lazyload.js 冲突
- java实例_Java线程方式及实例
- Tricks(三十二)—— 二维数组转换为一维数组
- 比特币网站Flexcoin遭黑客攻击 损失极大 被迫关闭
- 手机号码归属地数据库下载
- bt种子磁力播放器 android,(安卓)种子磁力在线播放器 — 可离线至本地
- 安卓APP测试要怎么测,测试流程和重点有哪些?我来告诉你
- RK3568-ANDROID11-降频DDR
- 4G摄像头采用GB28181协议成功接入LiveGBS国标流媒体平台的设置流程
- 【论文】如何记论文笔记
- 程序员的呓语---萎缩的情商
- Shell(bash)脚本入门
- python小波变换去噪
- 豆瓣首席架构师洪强宁谈Python语言