新特性
一、Lambda表达式
*
* Lambda表达式
* 是一种没有名字的函数,也可称为闭包,是Java8的新特性
* 本质上是一段匿名内部类,也可以是一段可传递的代码。也称箭头函数
* 特点:
* 允许把函数作为一个方法的参数(函数作为参数传递到方法中)
* 使用Lambda表达式可以让代码变得更加简洁
* 应用场景:
* 列表迭代、Map映射、Reduce聚合、想替代一个不想命名的函数或类,该函数或类往往并不复杂、
* 想尽量缩短代码量的场景
* 具体语法:
* 1、(parameters)->expression
* 2、(parameters)->{
statements;}
* 语法特点:
* 可选类型声明:不需要声明参数类型,编译器可以统一识别参数值
* 可选参数圆括号:一个参数无需定义圆括号,多个参数需要定义
* 可选大括号:如果主体只包含一个语句,就不需要大括号
* 可选的返回关键字:如果表达式只有一个返回值则编译器自动返回值,大括号需要指明表达式返
* 回了一个数值
* 案例:
* ()->5 不需要参数,返回值为5
* x->2*x 接受一个参数(数字类型),返回其2倍值
* (x,y)->x-y 接收两个参数,返回其差值
* (int x, int y)->x+y 接收两个int类型整数,返回和
* (String s)->System.out.print(s) 接收一个String对象,控制台打印
* 闭包:是能够读取其他函数内部变量的函数
* 在Java中,方法内部的局部变量只能在方法内使用,所以闭包可以理解为函数内部的函数
* 闭包本质是将函数内部和函数外部连接起来的桥梁
* */
public class Lambda_01 {
public static void main(String[] args) {
// 遍历
String[] strings = {
"one","two","three"};
List<String> list = Arrays.asList(strings);
// jdk1.7-老版
for (String string : list) {
System.out.println(string);
}
System.out.println("-------------");
// jdk1.8。也叫箭头函数
list.forEach(x->{
System.out.println(x);
});
// 类似于下面写法。相当于自己创建了一个方法,然后遍历调用这个方法
// 把集合中每个元素作为参数传递进入并打印
for (String string : list) {
test(string);
}
}
public static void test(String string){
System.out.println(string);
}
}
/*
* 列表排序
* */
public class lambda_02 {
public static void main(String[] args) {
Integer[] arr = {
4,6,1,2,7};
List<Integer> list = Arrays.asList(arr);
System.out.println(list);
list.sort(new Comparator<Integer>() {
@Override
public int compare(Integer o1, Integer o2) {
return o1-o2;
}
});
System.out.println(list);
Integer[] arr1 = {
4,6,1,2,7};
list = Arrays.asList(arr1);
System.out.println(list);
// 如果只有一条语句,并且是返回值语句,可以不写return和{}
// 如果写上{}, 就必须写return和;
// 如果有多条语句。必须写 {}、return、;
list.sort((x,y)->y-x);
System.out.println(list);
}
}
二、函数式接口
*
* 函数式接口(FunctionalInterface)
* 本质是 一个有且仅有一个抽象方法,但是可以有多个非抽象方法的接口
* 核心是为了为Lambda表达式提供更好的支持,进一步达到函数式编程的目标。
* 通过函数式编程极大提高编程效率
* 可以被隐式转换为lambda表达式
* 特点:
* 函数式接口是只定义一个抽象方法的接口
* 可以包含一个或多个静态或默认方法
* 专用注解@FunctionalInterface 检查此接口是否是一个函数式接口,也可不添加该注解
* 如果有两个或以上 抽象方法,就不能当做函数式接口使用,也不能添加@FunctionalInterface注解
* 如果只有一个抽象方法,@FunctionalInterface注解可省略
* 简单地说是回调函数,方法的参数是一个方法,在方法中对传递的方法进行调用
* */
public class _01_FuncInterface {
public static void main(String[] args) {
// 1.8之前编码方式
// 方式1:实现类写法
Test test = new Test();
call(test);
// 方式2:匿名内部类写法
call(new MyFunctionInter() {
@Override
public void printMessage() {
System.out.println("匿名内部类写法");
}
});
// 1.8新特性
// 方式1:直接在call函数中传入箭头函数
// 箭头函数等于是实现类中实现了这个抽象方法,不过不用写实现类。且比匿名内部类实现简单
call( ()->{
System.out.println("lambda写法");
} );
// 方式2:先创建函数对象,类似于实现类接口的内部类对象
MyFunctionInter inter = ()->{
System.out.println("保存为函数对象变量。再调用");
};
call(inter);
// 调用实现方式2的这个方法
inter.printMessage();
}
// 自定义静态方法,接收接口对象
public static void call(MyFunctionInter func){
func.printMessage();
}
}
// 函数式接口,只能有一个抽象方法。但可以有默认方法
@FunctionalInterface
interface MyFunctionInter{
void printMessage();
}
// 实现类
class Test implements MyFunctionInter{
@Override
public void printMessage() {
System.out.println("实现类写法");
}
}
/*
* 函数式接口-有参
* */
public class _02_FuncInterface {
public static void main(String[] args) {
// 1.8新特性
// 方式1:直接在call函数中传入箭头函数
// 箭头函数等于是实现类中实现了这个抽象方法,不过不用写实现类。且比匿名内部类实现简单
call( (str)->{
System.out.println(str);
}, "参数1" );
// 方式2:先创建函数对象,类似于实现类接口的内部类对象
MyFunctionInter_02 inter = (str)->{
System.out.println(str);
};
call(inter,"参数2");
// 调用实现方式2的这个方法
inter.<