JDK1.8新特性(一) ----Lambda表达式、Stream API、函数式接口、方法引用
- Lambda表达式
- Stream API
- 函数式接口
- 方法引用和构造器调用
- 接口中的默认方法和静态方法
- 新时间日期API
- default


现在JDK1.8给我们提供了新的方式Lambda表达式,比上边的两个例子编写的代码更为简单更简介,下面我们来看一看怎么比上边的代码更简单。







//3.终止操作
/**
* 查找和匹配
* allMatch-检查是否匹配所有元素
* anyMatch-检查是否至少匹配一个元素
* noneMatch-检查是否没有匹配所有元素
* findFirst-返回第一个元素
* findAny-返回当前流中的任意元素
* count-返回流中元素的总个数
* max-返回流中最大值
* min-返回流中最小值
*/
//3.1:allMatch检查是否匹配所有元素是否都成立,都成立返回true 否则返回false
Stream<Map<String, Object>> stream2 = maps.stream();
boolean a = stream2.allMatch(x -> Integer.valueOf(x.get("age").toString()) > 16);
System.err.println("结果:"+a); //false
//3.2:anyMatch检查是否至少匹配一个元素,只要有一个成立就返回true
Stream<Map<String, Object>> stream3 = maps.stream();
boolean b = stream3.anyMatch(x -> Integer.valueOf(x.get("age").toString()) > 16);
System.err.println("结果:"+b); //true
//3.3:noneMatch检查是否没有匹配所有元素,因为有成立的所以有匹配的元素,估 不成立
Stream<Map<String, Object>> stream4 = maps.stream();
boolean c = stream4.noneMatch(x -> Integer.valueOf(x.get("age").toString()) > 16);
System.err.println("结果:"+c); //false
//3.4:findFirst返回第一个元素,按照年龄从小到大排序返回第一个元素
Stream<Map<String, Object>> stream5 = maps.stream();
Map<String, Object> first = stream5.sorted((x,y) -> Integer.compare(Integer.valueOf(x.get("age")
.toString()),Integer.valueOf(y.get("age").toString()))).findFirst().get();
System.err.println(first.toString());//{sex=女, name=小红, age=16}
//3.5:findAny-返回当前流中的任意元素
Stream<Map<String, Object>> stream6 = maps.stream();
Map<String, Object> map = stream6.sorted((x,y) -> Integer.compare(Integer.valueOf(y.get("age")
.toString()),Integer.valueOf(x.get("age").toString()))).findAny().get();
//多次测试返回固定是这个,感觉因该是内部有一个算法排序然后返回其中固定某个 {sex=男, name=小明, age=18}
//排序之后返回的永远是第一个
System.err.println(map.toString());
//3.6:返回流中元素的总个数
Stream<Map<String, Object>> stream7 = maps.stream();
long count = stream7.count();
System.err.println("长度为:"+count); // 长度为:3
//TODO 最大最小就不测试了,自己可以试试
还有功能比较强大的两个终止操作 reduce和collect
/**
* reduce :规约操作
* 计算和
* 计算结果作为x,再从数组中取出新值作为y,进行下一步计算
* 结果在加上0 是最后的结果
*/
List<Integer> list = Arrays.asList(1,2,3,4,5,6,7,8,9,10);
Integer count2 = list.stream().reduce(0, (x, y) -> x + y);
System.out.println(count2); Stream<Map<String, Object>> stream8 = maps.stream();
//计算总年龄 也可以是浮点型数据 将Integer 换成Double就ok
Optional<Integer> op = stream8.map(m -> Integer.valueOf(String.valueOf(m.get("age"))))
.reduce(Integer::sum);
System.err.println(op.get()); //
/**
* collect操作:Collect-将流转换为其他形式,
* 接收一个Collection接口的实现,用于给Stream中元素做汇总的方法
* Collectors.toList()/toSet()
*/
Set<Integer> ageList = list.stream().collect(Collectors.toSet());
ageList.stream().forEach(System.out::println);
//取名字,封装成hashset
HashSet<Integer> hs = list.stream()
.collect(Collectors.toCollection(HashSet::new));
System.err.println(hs.toString());
函数式接口:
@FunctionalInterfaceinterface GreetingService
{
void sayMessage(String message);
} // 那么就可以使用Lambda表达式来表示该接口的一个实现(注:JAVA 8 之前一般是用匿名类实现的):
GreetingService greetService1 = message -> System.out.println("Hello " + message);
/**
* @MethodName: functionInterface
* @Description: 四大函数式接口练习
* @param
* @return
* @author rongrong
* @date 2019-12-23
*/
public void functionInterface(){
/**
* 1.Consumer 《T》:消费型接口,有参无返回值
* 打印:
* 222222
* hello
*/
changeStr("hello",(str) -> System.err.println(str)); /**
* 2.Supplier 《T》:供给型接口,无参有返回值
* 打印:
* 111111
* str
*/
String value = getValue(() -> "str");
System.err.println(value); /**
* 3. Function 《T,R》::函数式接口,有参有返回值
* 打印:
* 333333
* 20000
*/
Long aLong = changeNum(100L, x -> x * 200);
System.err.println(aLong);
/**
* Predicate《T》: 断言型接口,有参有返回值,返回值是boolean类型
* 打印:
* true
*/
boolean rongrong = changeBoolean("rongrong", x -> x.equals("rongrong"));
System.err.println(rongrong); } /**
* Consumer<T> 消费型接口
* @param str
* @param con
*/
public void changeStr(String str, Consumer<String> con){
System.err.println("222222");
con.accept(str);
} /**
* Supplier<T> 供给型接口
* @param sup
* @return
*/
public String getValue(Supplier<String> sup){
System.err.println("111111");
return sup.get();
} /**
* Function<T,R> 函数式接口
* @param num
* @param fun
* @return
*/
public Long changeNum(Long num, Function<Long, Long> fun){
System.err.println("333333");
return fun.apply(num);
} /**
* Predicate<T> 断言型接口
* @param str
* @param pre
* @return
*/
public boolean changeBoolean(String str, Predicate<String> pre){
return pre.test(str);
}
在四大核心函数式接口基础上,还提供了诸如BiFunction、BinaryOperation、toIntFunction等扩展的函数式接口,都是在这四种函数式接口上扩展而来的,不做赘述。
/**
*注意:
* 1.lambda体中调用方法的参数列表与返回值类型,要与函数式接口中抽象方法的函数列表和返回值类型保持一致!
* 2.若lambda参数列表中的第一个参数是实例方法的调用者,而第二个参数是实例方法的参数时,可以使用ClassName::method
* 下边写的例子 上边是不简化时的写法,下边的是对应的简化写法,就是方法引用
*/ //100
//
Consumer<Integer> con = (x) -> System.out.println(x);
con.accept(100);
// 方法引用-对象::实例方法
Consumer<Integer> con2 = System.out::println;
con2.accept(200); // 方法引用-类名::静态方法名
BiFunction<Integer, Integer, Integer> biFun = (x, y) -> Integer.compare(x, y);
Integer apply = biFun.apply(100, 200);
BiFunction<Integer, Integer, Integer> biFun2 = Integer::compare;
Integer result = biFun2.apply(100, 200);
//-1:-1
System.err.println(apply + ":" + result); // 方法引用-类名::实例方法名
BiFunction<String, String, Boolean> fun1 = (str1, str2) -> str1.equals(str2);
Boolean apply1 = fun1.apply("rong", "rong");
BiFunction<String, String, Boolean> fun2 = String::equals;
Boolean result2 = fun2.apply("hello", "world");
//true:false
System.out.println(apply1 + ":" + result2);
// 构造方法引用 类名::new
Supplier<String> sup = () -> new String();
System.out.println(sup.get());
Supplier<String> sup2 = String::new;
System.out.println(sup2.get()); // 构造方法引用 类名::new (带一个参数)
//x 代表是传进去的参数,也就是泛型中的Integer类型
//new String(...) 代表泛型中的String类型
Function<Integer, String> fun = x -> new String(String.valueOf(x));
System.err.println(fun.apply(100));
Function<String, String> fun3 = String::new;
System.out.println(fun3.apply("100"));
// 数组引用
Function<Integer, String[]> arrayFun = (x) -> new String[x];
Function<Integer, String[]> arrayFun2 = String[]::new;
//给String数组设置了两个长度。但是值是null
String[] strArray = arrayFun2.apply(2);
Arrays.stream(strArray).forEach(System.out::println);
序号
|
接口 & 描述
|
1
|
BiConsumer<T,U>
代表了一个接受两个输入参数的操作,并且不返回任何结果
|
2
|
BiFunction<T,U,R>
代表了一个接受两个输入参数的方法,并且返回一个结果
|
3
|
BinaryOperator<T>
代表了一个作用于于两个同类型操作符的操作,并且返回了操作符同类型的结果
|
4
|
BiPredicate<T,U>
代表了一个两个参数的boolean值方法
|
5
|
BooleanSupplier
代表了boolean值结果的提供方
|
6
|
Consumer<T>
代表了接受一个输入参数并且无返回的操作
|
7
|
DoubleBinaryOperator
代表了作用于两个double值操作符的操作,并且返回了一个double值的结果。
|
8
|
DoubleConsumer
代表一个接受double值参数的操作,并且不返回结果。
|
9
|
DoubleFunction<R>
代表接受一个double值参数的方法,并且返回结果
|
10
|
DoublePredicate
代表一个拥有double值参数的boolean值方法
|
11
|
DoubleSupplier
代表一个double值结构的提供方
|
12
|
DoubleToIntFunction
接受一个double类型输入,返回一个int类型结果。
|
13
|
DoubleToLongFunction
接受一个double类型输入,返回一个long类型结果
|
14
|
DoubleUnaryOperator
接受一个参数同为类型double,返回值类型也为double 。
|
15
|
Function<T,R>
接受一个输入参数,返回一个结果。
|
16
|
IntBinaryOperator
接受两个参数同为类型int,返回值类型也为int 。
|
17
|
IntConsumer
接受一个int类型的输入参数,无返回值 。
|
18
|
IntFunction<R>
接受一个int类型输入参数,返回一个结果 。
|
19
|
IntPredicate
:接受一个int输入参数,返回一个布尔值的结果。
|
20
|
IntSupplier
无参数,返回一个int类型结果。
|
21
|
IntToDoubleFunction
接受一个int类型输入,返回一个double类型结果 。
|
22
|
IntToLongFunction
接受一个int类型输入,返回一个long类型结果。
|
23
|
IntUnaryOperator
接受一个参数同为类型int,返回值类型也为int 。
|
24
|
LongBinaryOperator
接受两个参数同为类型long,返回值类型也为long。
|
25
|
LongConsumer
接受一个long类型的输入参数,无返回值。
|
26
|
LongFunction<R>
接受一个long类型输入参数,返回一个结果。
|
27
|
LongPredicate
R接受一个long输入参数,返回一个布尔值类型结果。
|
28
|
LongSupplier
无参数,返回一个结果long类型的值。
|
29
|
LongToDoubleFunction
接受一个long类型输入,返回一个double类型结果。
|
30
|
LongToIntFunction
接受一个long类型输入,返回一个int类型结果。
|
31
|
LongUnaryOperator
接受一个参数同为类型long,返回值类型也为long。
|
32
|
ObjDoubleConsumer<T>
接受一个object类型和一个double类型的输入参数,无返回值。
|
33
|
ObjIntConsumer<T>
接受一个object类型和一个int类型的输入参数,无返回值。
|
34
|
ObjLongConsumer<T>
接受一个object类型和一个long类型的输入参数,无返回值。
|
35
|
Predicate<T>
接受一个输入参数,返回一个布尔值结果。
|
36
|
Supplier<T>
无参数,返回一个结果。
|
37
|
ToDoubleBiFunction<T,U>
接受两个输入参数,返回一个double类型结果
|
38
|
ToDoubleFunction<T>
接受一个输入参数,返回一个double类型结果
|
39
|
ToIntBiFunction<T,U>
接受两个输入参数,返回一个int类型结果。
|
40
|
ToIntFunction<T>
接受一个输入参数,返回一个int类型结果。
|
41
|
ToLongBiFunction<T,U>
接受两个输入参数,返回一个long类型结果。
|
42
|
ToLongFunction<T>
接受一个输入参数,返回一个long类型结果。
|
43
|
UnaryOperator<T>
接受一个参数为类型T,返回值类型也为T。
|
JDK1.8新特性(一) ----Lambda表达式、Stream API、函数式接口、方法引用的更多相关文章
- jdk1.8新特性之lambda表达式
lambda表达式其实就是指一个匿名函数,应用最广泛的就是匿名内部类的简化.在jdk1.8之前,我们定义一个匿名内部类可能需要写一大坨代码,现在有了lambda之后,可以写的很简洁了.但不是说lamb ...
- jdk1.8新特性之lambda表达式及在Android Studio中的使用举例
Jdk1.8已经出很久了但是很多同学对它的特性在android studio 中的应用可能还不是很熟悉,今天我们就来对这个新特性在AS中做它的应用实践. 一.首先在有JDK1.8的情况下我们要在AS的 ...
- Java8 新特性学习 Lambda表达式 和 Stream 用法案例
Java8 新特性学习 Lambda表达式 和 Stream 用法案例 学习参考文章: https://www.cnblogs.com/coprince/p/8692972.html 1.使用lamb ...
- java8新特性: lambda表达式:直接获得某个list/array/对象里面的字段集合
java8新特性: lambda表达式:直接获得某个list/array/对象里面的字段集合 比如,我有一张表: entity Category.java service CategoryServic ...
- java8新特性之——lambda表达式的使用
lambda表达式简介 个人理解,lambda表达式就是一种新的语法,没有什么新奇的,简化了开发者的编码,其实底层还是一些常规的代码.Lambda 是一个匿名函数,我们可以把 Lambda 表达式理解 ...
- 【Java8新特性】Lambda表达式基础语法,都在这儿了!!
写在前面 前面积极响应读者的需求,写了两篇Java新特性的文章.有小伙伴留言说:感觉Lambda表达式很强大啊!一行代码就能够搞定那么多功能!我想学习下Lambda表达式的语法,可以吗?我的回答是:没 ...
- 【Java8新特性】- Lambda表达式
Java8新特性 - Lambda表达式 生命不息,写作不止 继续踏上学习之路,学之分享笔记 总有一天我也能像各位大佬一样 一个有梦有戏的人 @怒放吧德德 分享学习心得,欢迎指正,大家一起学习成长! ...
- Java 8新特性-3 Lambda 表达式
在 Java 8 之前,匿名内部类,监听器和事件处理器的使用都显得很冗长,代码可读性很差. 在Java 8 之前使用匿名内部类: 例如 interface ITestPrint{ public voi ...
- java8的新特性之lambda表达式和方法引用
1.1. Lambda表达式 通过具体的实例去体会lambda表达式对于我们代码的简化,其实我们不去深究他的底层原理和背景,仅仅从用法上去理解,关注两方面: lambda表达式是Java8的一个语法糖 ...
随机推荐
- linux内核中IS_ALIGNED是如何定义的?
1. 定义如下: (include/linux/kernel.h) #define IS_ALIGNED(x, a) (((x) & ((typeof(x))(a ...
- SVG-概述/容器与通用属性
参考: SVG 图像入门教程 MDN SVG SVG教程 SVG入门-踏得 工具: svg在线编辑 概述 SVG 是一种基于 XML 语法的图像格式,全称是可缩放矢量图(Scalable Vector ...
- Android:StateMachine 之 WifiStateMachine
一.状态图: 二.代码分析: \frameworks\opt\net\wifi\service\java\com\android\server\wifi\WifiStateMachine.java 1 ...
- ISO/IEC 9899:2011 条款6.4.9——注释
6.4.9 注释 1.除了在一个字符常量.一个字符串字面量.或一个注释内,字符 /* 引入一个注释.这么一个注释的内容被检查仅用于标识多字节字符,并且要找到 */ 来终结.[注:从而,/* ... * ...
- Eclipse中把项目导出为war包【我】
项目右键,Export 全部默认一路下一步,选择一个目标文件夹,确定即可.
- 123457123457#0#-----com.yuming.drawGame01--前拼后广--儿童画画游戏
com.yuming.drawGame01--前拼后广--儿童画画游戏
- LeetCode_110. Balanced Binary Tree
110. Balanced Binary Tree Easy Given a binary tree, determine if it is height-balanced. For this pro ...
- 使用python或robotframework调multipart/form-data接口上传文件
这几天调一个multipart/form-data类型的接口,遇到点小阻碍.之前同事有使用urllib库写了个类似的方法实现,比较长,想要改的时候发现不太好使.在网上查找发现用requests库做这个 ...
- EasyNetQ使用(七)【发布者确认 ,用Future Publish发布预定中事件 】
AMQP发布消息默认情况下是非事务性的,不能确保你的消息真正送达代理.AMQP可以去指定事务性发布,但是RabbitMQ这样会非常慢,我们没有让EasyNetQ API去支持此功能.为了高效的确保投递 ...
- SSRF——漏洞利用(二)
0x01 概述 上篇讲述了SSRF的一般用法,用http协议来进行内网探测,攻击内网redis,接下来讨论的是SSRF的拓展用法,通过,file,gopher,dict协议对SSRF漏洞进行利用. 0 ...