Jdk1.8在2014年三月发布,增添了很多新特性
-
lambda表达式
lambda表达式可以称之为闭包,是java8中的一个重要特性
很多用法都用带了此表达式
lambda表达式允许把函数作为方法的参数传递,使代码更加简洁
语法:
(parameters)->expression代码块
或者
(parameters)->{statement代码块}
说明:
可选参数声明:不需要声明参数的类型,编译器同一识别参数值
可选参数圆括号:一个参数无需定义括号,多个参数需要定义圆括号
可选大括号:代码主题只含有一个语句,则不需要使用大括号
可选返回关键字:如果主题只有一个表达式,返回值,编译器会自动返回值,大括号需要指定返回一个数据
比如:
//不需要参数,但是返回值是5
()->5
//接受一个参数(推断出是数字类型),返回值参数的二倍
x->x*2
//接收两个参数,推断出是数字类型,返回参数的差值
(a,b)->a-b
//接收一个String类型的参数,并输出参数的值,推断出无返回值
//相当于方法的返回类型是void
(String str)->System.out.println(str);
其实lambda表达式的本质就是接口的子实现,lambda表达式简化了内部类的写法
lambda表达式的另外一个说法是函数式编程,代码中看不到类,只能看到方法/函数
使用lambda表达式的作用域:
lambda表达式的作用域
-
引用外层成员变量
外层成员变量被final修饰的,则在lambda内部不能修改成员变量的值
外层成员变量被final修饰
-
Lambda表达式的局部变量不用声明为final,但是必须不能被后面代码所修改
即隐式的final特性
-
Lambda表达式不允许声明一个与局部变量同名的参数或者局部变量
-
方法的引用 其本质还是lambda表达式
方法的引用有四种方式 类名::方法名
具体写法有四种:
1.构造器的引用 语法: Class :: new
2.静态方法的引用 语法: Class :: static method
3.特定类任意的对象引用 语法: Class :: 非静态方法名称
4.特定对象的方法的引用 语法: instance对象 :: 非静态方法的名称
-
默认方法
在接口中可以放置有方法体的方法,但是方法前必须要用default修饰
接口中添加默认方法是用来给所有的子类提供同一个功能
接口中还可以放置静态方法,而且静态方法带有方法体
-
函数式接口
函数式接口(FunctionInterFace)就是有一个且只有一个抽象方法
但是可以有多个非抽象方法的接口
函数式接口可以用lambda表达式,也可以用方法的引用
Jdk1.8之前已经有部分函数式接口
比如:
java.lang.Runnable
java.util.Comparator
java.io.FileFilter
...等
在jdk8之后新添加的函数式接口
java.util.Function 其中包含了很多的类
比如:
Consumer<T>
Pridicate<T>
Supplier<T>
...等
-
Java和java script的交互
-
Stream api流api 管道的概念
在java8中添加了一个新的抽象,称之为流stream
可以让程序员以一种声明式的方式处理数据
Stream流处理方式: 可以把要处理的元素看成是一种流,流在管道中传输,并且在管道的节点上进行处理
处理包含:筛选,排序,聚合等操作
元素流在管道中经过中间操作的处理,左后有最终的操作的得到处理结果
Stream流管道的几个名词解释:
数据源:流的源头,可以是集合,数组,io,其他数据源
聚合操作:就是在流中筛选数据的操作
比如:filter,map,reduce,find,match,sorted等…
生成stream流的源头:
-stream() 生成一个串行流
-parallelStream() 生成一个并行流
比如:
List<String> strs=Arrays.asList("abc","bc","cda","qaz","wqe","");
List<String> filtered=strs.stream().filter(str->!str.isEmpty()).collect(Collectors.toList());
Stream流的forEach()方法
forEach()方法用来迭代流中的每一个数据:
Random random=new Random();
random.ints(0,100).limit(10).sorted().forEach(System.out::println);
//循环输出100以内10个随机数
//sorted() 方法用于对指定的流排序
map方法用于映射每一个元素对应的结果:
List<Integer> numbers=Arrays.asList(3,2,3,7,3,5);
List<Integer> square8_5=numbers.stream().map(i->i*i).distinct().collect(Collectors.toList());
System.out.println(square8_5);
filter方法用于通过设置条件过滤出符合条件的元素
limit方法用于获取指定数量的流
Random random=new Random();
random.ints(0,100).limit(10).sorted().forEach(System.out::println);
Collectors类 实现了很多的规约操作
比如:
-toList()是规约
List<String> filtered8_3=strs.stream().filter(str->!str.isEmpty()).collect(Collectors.toList());
//把strs集合中的非空元素取出转换成list集合
-joining() 是规约
String merge8_4=strs.stream().filter((str)->!str.isEmpty()).collect(Collectors.joining(","));
//把集合中的非空元素取出组成字符串,并用逗号间隔
-
Date-Time api,对java7以前的日期类的加强
java8通过发布型的Date-time api(JSR310) 来进一步加强对日期与时间的处理
在旧版中,日期和时间的api存在许多问题,
1.非线程安全 java.util.Date是非线程安全的
所有的日期都是可变的
2.设计很差,java.util.Date跟java.sql.Date类都是日期类,重复定义很多
所以java用java.util.Calendar类替换
3.时区处理很麻烦,在java.util.Date中并没有提供时区处理的api
java.util.Calendar控制时区
java.util.TimeZone控制时区
在java8中有一个包叫java.time包,提供了很多新的api
-Local(本地):简化了日期和时间的处理,没有时区的问题
-Zoned(时区):通过制定的时区处理日期时间
-
Option类 java中专门用来结局空指针异常的问题
-
Base64类 专门用来对数据做编码和解码