价值300RMB的Java8新特性总结_01

主要新特性:

1,**Lambda 表达式** − Lambda允许把函数作为一个方法的参数(函数作为参数传递进方法中。)
2,**方法引用** − 方法引用提供了非常有用的语法,可以直接引用已有Java类或对象(实例)的方法或构造器。与lambda联合使用,方法引用可以使语言的构造更紧凑简洁,减少冗余代码。
3,**默认方法** − 默认方法就是一个在接口里面有了一个实现的方法。
4,**Stream API** −新添加的Stream API(java.util.stream) 把真正的函数式编程风格引入到Java中。
5,**Date Time API** − 加强对日期与时间的处理。
6,**Optional 类** − Optional 类已经成为 Java 8 类库的一部分,用来解决空指针异常。
7,Nashorn, JavaScript 引擎 − Java 8提供了一个新的Nashorn javascript引擎,它允许我们在JVM上运行特定的javascript应用。

接口的默认方法?接口中的默认方法主要就是接口这种语法结构本身的语法特点

传统的方法?
	:在Java8之前Java中接口里面的方法默认都是public abstract 修饰的抽象方法并且没有方法体
static方法?
	:1、使用static修饰接口中的方法并且必须有主体;2、接口的static方法只能够被接口本身调用;接口名.方法名(...);3、接口的static方法不能够被子接口继承;4、接口的static方法不能够被实现类覆写及直接调用
default方法?
	:在接口中可以定义一个使用default修饰有方法体的方法,接口中可以对这个方法提供默认的一种实现。
		1、使用default修饰接口中的方法并且必须有主体;2、接口的default方法不能够被接口本身调用,需要接口的实例(实现类对象)来调用;3、接口的default方法可以背子接口继承、覆写或者直接调用;4、接口的default方法可以被实现类覆写及直接调用;
		在接口中,经过static和default修饰的方法必须有方法体;static修饰的方法调用方式为类.方法名default修饰的方法必须是实现类的对象调用static修饰的方法不能被子接口继承,default修饰的方法可以被子接口继承并复写方法,就可以创建子接口实现类对象进行调用

函数式接口

什么是函数式接口?
	:函数式接口(Functional Interface)就是一个有且仅有一个抽象方法,但是可以有多个非抽象方法的接口。函数式接口可以被隐式转换为lambda表达式,可以使用注解@FunctionalInterface标记该接口为函数式接口。
函数式接口API?
	:JDK 1.8之前已有的函数式接口:
			java.lang.Runnable
			java.util.concurrent.Callable
			java.security.PrivilegedAction
			java.util.Comparator
			java.io.FileFilter
			java.nio.file.PathMatcher
			java.lang.reflect.InvocationHandler
			java.beans.PropertyChangeListener
			java.awt.event.ActionListener
			javax.swing.event.ChangeListener
		JDK 1.8 新增加的函数接口:
			java.util.function 此包中包含了很多类,用来支持 Java的 函数式编程
函数式接口注解
	@FunctionalInterface
	我们在函数式接口上面加上此注解后,里面就只能够有一个抽象方法了,当然不加此注解且只有一个抽象方法的接口也是函数式接口,只是没有限定提示而已。						

Lambda表达式

什么是Lambda表达式?
	简单来说:可以看成是对匿名内部类的简写,使用Lambda表达式时,接口必须是函数式接口。
Lambda表达式的语法?
	基本语法:
		<函数式接口>  <变量名> = (参数1,参数2...) -> {
                    //方法体
         }
    特点说明:
	(参数1,参数2…)表示参数列表;->表示连接符;{}内部是方法体 
		1、=右边的类型会根据左边的函数式接口类型自动推断; 
		2、如果形参列表为空,只需保留(); 
		3、如果形参只有1个,()可以省略,只需要参数的名称即可; 
		4、如果执行语句只有1句,且无返回值,{}可以省略,若有返回值,则若想省去{},则必须同时省略return,且执行语句也保证只有1句; 
		5、形参列表的数据类型会自动推断; 
		6、lambda不会生成一个单独的内部类文件; 
		7、lambda表达式若访问了局部变量,则局部变量必须是final的,若是局部变量没有加final关键字,系统会自动添加,此后在修改该局部变量,会报错;

一个案例学会Lambda
1、一个类实现一个接口基本写法
接口:
在这里插入图片描述
实现类:
在这里插入图片描述
测试类:
在这里插入图片描述
2、匿名内部类的写法
在这里插入图片描述
3、使用Lambda写法一:常规写法
我们可以看成是把函数式接口中唯一的实现方法的核心: 方法列表和方法体抽取出来
在这里插入图片描述
4、使用Lambda写法二:两个参数有返回值的简写
在这里插入图片描述
5、使用Lambda写法三:一个参数没有返回值的简写
测试如果只有一个参数的简写
接口:
在这里插入图片描述
测试类:
在这里插入图片描述
6、使用Lambda写法四:没有参数的简写
测试如果函数式接口中的方法没有参数
接口:
在这里插入图片描述
测试类:
在这里插入图片描述

Lambda 作用域

在lambda表达式中访问外层作用域和老版本的匿名对象中的方式很相似。你可以直接访问标记了final的外层局部变量,或者实例的字段以及静态变 量。但如果访问局部变量,要求局部变量必须是final修饰的
在这里插入图片描述
注意:上面代码中一旦匿名内部类中使用了i,则第5行的i会自动被编辑为final的
下面我们可以看到使用Lambda表达式和上面一样的
在这里插入图片描述

方法引用

构造方法引用
1、准备一个一个Person类,提供一个两个参数的构造方法
在这里插入图片描述
2、准备一个创建Person对象的工厂函数式接口,提供一个获得Person对象的抽象方法
在这里插入图片描述
3、使用匿名内部类的方式创建一个工厂的实例
在这里插入图片描述
4、使用Lambda表达式简写一:
在这里插入图片描述
5、使用Lambda表达式简写二:
在这里插入图片描述
静态方法引用
1、准备一个函数式接口,提供一个解析字符串为int的方法
在这里插入图片描述
2、测试
在这里插入图片描述
实例方法引用
1、了解Java1.8提供了一个函数式接口Function,接受两个参数
在这里插入图片描述
2、匿名内部类方式
在这里插入图片描述
3、Lambda表达式常规写法
在这里插入图片描述
4、Lambda表达式简写
在这里插入图片描述

Java 8 Stream

Java 8 API添加了一个新的抽象称为流Stream,可以让你以一种声明的方式处理数据。
Stream 使用一种类似用 SQL 语句从数据库查询数据的直观方式来提供一种对 Java 集合运算和表达的高阶抽象。
select * from user where age >30
Stream API可以极大提高Java程序员的生产力,让程序员写出高效率、干净、简洁的代码。
这种风格将要处理的元素集合看作一种流, 流在管道中传输, 并且可以在管道的节点上进行处理, 比如筛选, 排序,聚合等。
元素流在管道中经过中间操作(intermediate operation)的处理,最后由最终操作(terminal operation)得到前面处理的结果。

什么是 Stream?

Stream(流)是一个来自数据源的元素队列并支持聚合操作
•	<strong元素队列< strong="">元素是特定类型的对象,形成一个队列。 Java中的Stream并不会存储元素,而是按需计算。</strong元素队列<>
•	数据源 流的来源。 可以是集合,数组,I/O channel, 产生器generator 等。
•	聚合操作 类似SQL语句一样的操作, 比如filter, map, reduce, find, match, sorted等。
和以前的Collection操作不同, Stream操作还有两个基础的特征:
•	Pipelining: 中间操作都会返回流对象本身。 这样多个操作可以串联成一个管道, 如同流式风格(fluent style)。 这样做可以对操作进行优化, 比如延迟执行(laziness)和短路( short-circuiting)。
•	内部迭代: 以前对集合遍历都是通过Iterator或者For-Each的方式, 显式的在集合外部进行迭代, 这叫做外部迭代。 Stream提供了内部迭代的方式, 通过访问者模式(Visitor)实现。

生成流:

	在 Java 8 中, 集合接口有两个方法来生成流:
	stream() − 为集合创建串行流。
	parallelStream() − 为集合创建并行流。

常用方法

forEach
Stream 提供了新的方法 'forEach' 来迭代流中的每个数据。以下代码片段使用 forEach 输出了10个随机数:
Random random = new Random(); 
random.ints().limit(10).forEach(System.out::println);

map
map 方法用于映射每个元素到对应的结果,以下代码片段使用 map 输出了元素对应的平方数:
List<Integer> numbers = Arrays.asList(3, 2, 2, 3, 7, 3, 5); 
// 获取对应的平方数 
List<Integer> squaresList = numbers.stream().map( i -> i*i).distinct().collect(Collectors.toList());

filter
filter 方法用于通过设置的条件过滤出元素。以下代码片段使用 filter 方法过滤出空字符串:
List<String>strings = Arrays.asList("abc", "", "bc", "efg", "abcd","", "jkl"); // 获取空字符串的数量 int count = strings.stream().filter(string -> string.isEmpty()).count();

limit
limit 方法用于获取指定数量的流。 以下代码片段使用 limit 方法打印出 10 条数据:
Random random = new Random();
random.ints().limit(10).forEach(System.out::println);

sorted
sorted 方法用于对流进行排序。以下代码片段使用 sorted 方法对输出的 10 个随机数进行排序:
Random random = new Random(); 
random.ints().limit(10).sorted().forEach(System.out::println);

并行(parallel)程序
parallelStream 是流并行处理程序的代替方法。以下实例我们使用 parallelStream 来输出空字符串的数量:
List<String> strings = Arrays.asList("abc", "", "bc", "efg", "abcd","", "jkl"); 
// 获取空字符串的数量 
int count = strings.parallelStream().filter(string -> string.isEmpty()).count();
我们可以很容易的在顺序运行和并行直接切换。

Collectors
Collectors 类实现了很多归约操作,例如将流转换成集合和聚合元素。Collectors 可用于返回列表或字符串:
List<String>strings = Arrays.asList("abc", "", "bc", "efg", "abcd","", "jkl"); 
List<String> filtered = strings.stream().filter(string -> !string.isEmpty()).collect(Collectors.toList()); 
System.out.println("筛选列表: " + filtered); 
String mergedString = strings.stream().filter(string -> !string.isEmpty()).collect(Collectors.joining(", ")); 
System.out.println("合并字符串: " + mergedString);

Optional 类

今天暂时写到这里

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值