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的一个语法糖 ...
 
随机推荐
- ISO/IEC 9899:2011 条款6.4.1——关键字
			
6.4.1 关键字 语法 1.以下为关键字: auto break case char const continue default do double ...
 - KDChart example
			
/******************************************************************************** ** Form generated ...
 - mouse without borders无界鼠标使用教程
			
mouse without borders无界鼠标使用教程 摘自https://www.jianshu.com/p/6a0209ad03f8 老黑随笔 关注 0.4 2018.05.18 11: ...
 - spark 入门学习    核心api
			
spark入门教程(3)--Spark 核心API开发 原创 2016年04月13日 20:52:28 标签: spark / 分布式 / 大数据 / 教程 / 应用 4999 本教程源于2016年3 ...
 - jq删除标签
			
<script>$(function(){ $("div").remove()})</script>
 - Select 优化
			
https://yq.aliyun.com/articles/704238?spm=a2c4e.11155472.0.0.66be4efeaUB5bk
 - Cas(01)——简介
			
Cas的全称是Centeral Authentication Service,是对单点登录SSO(Single Sign On)的一种实现.其由Cas Server和Cas Client两部分组成,C ...
 - Http协议!(转)
			
背景 我们在测试中,经常与http协议, URL打交道,不时会修改URL的参数来达到不同的测试目的或者转到不同的页面,那么,你对HTTP协议了解多少呢?今天我们来总结下. #1 HTTP协议简介 HT ...
 - 《Fluid Engine Development》 学习笔记3-光滑粒子流体动力学
			
用粒子表示流体最热门的方法就是就是光滑粒子流体动力学(Smoothed Particle Hydrodynamics (SPH).) 这种方法模糊了流体的边界,用有限数量的粒子代表流体,该方法的基本思 ...
 - QT信号槽连接
			
一:信号槽是什么? Qt的信号和槽机制是Qt的一大特点,实际上这是和MFC中的消息映射机制相似的东西,要完成的事情也差不多,就是发送一个消息然后让其它窗口响应,当然,这里的消息是广义的说法,简单点说就 ...