JDK8之后新特性
函数式接口
当接口中的抽象方法仅有一个时,但是可以允许有其他的方法。这样的接口叫做函数式接口
一般使用:@FunctaInterface进行标记
@FunctionalInterface
public interface Runnable{
public void run();
}
Lambda表达式
- 标准格式
(数据类型1 参数1,数据类型2 参数2) -> { 语句体; return 结果; }
- 简化格式
//可以省略数据类型
(参数1,参数2) -> { 语句体; return 结果; }
//如果语句体只有一条语句,{}和return可以省略
(参数1,参数2) -> 语句体;
//如果参数只有一个,()可以省略
参数->语句体;
Lambda表达式的应用
- 使用步骤
1.在使用Lambda表达式之前必须要先有一个函数式接口
2.再写一个方法,把函数式接口作为方法的形式参数
3.在调用方法时,传递Lambda表达式作为函数式接口的实现
- 练习1
@FunctionalInterface
public interface Eatable{
public void eat();
}
public class Demo1{
public static void main(String[] args){
//调用方法传递匿名内部类
method(new Eatable(){
public void eat(){
System.out.println("吃鱼");
}
});
//调用方法传递Lamdba表达式
method(()->{
System.out.println("吃鱼");
}
);
}
//把函数式接口作为方法的形式参数
public static void method(Eatable a){
a.eat();
}
}
- 练习2
@FunctionalInterface
public interface Calculator {
public int calc(int a,int b);
}
public class Demo3 {
public static void main(String[] args) {
//Lambda表达式,实现对两个数求和
method((int a,int b)->{
return a+b;
});
//Lambda表达式,实现对两个数求差
method((int a,int b)->{
return a-b;
});
//Lambda表达式,实现对两个数求乘积
method((a, b)->a*b);
}
public static void method(Calculator c){
//使用Calculator的calc方法对50和40进行计算,把计算的结果赋值给result
int result = c.calc(50, 40);
System.out.println(result);
}
}
- 改进版
public class Demo3 {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
System.out.println("键盘录入一个整数");
int i = scanner.nextInt();
System.out.println("键盘再录入一个整数");
int j= scanner.nextInt();
method((int a,int b)->{
return a+b;
},i,j);
method(new Calculator() {
@Override
public int calc(int a, int b) {
return a*b;
}
},i,j);
}
public static void method(Calculator c,int a,int b){
int result = c.calc(a, b);
System.out.println(result);
}
}
接口新特性
从JDK8开始接口中更新了一些组成部分
1.常量:
默认被 public static final 修饰; (可以省略)
2.抽象方法:
默认被 public abstract 修饰; (可以省略)
【实现类必须重写接口中所有的抽象方法】
3.默认方法(default)
被 public default 修饰;(public可以省略)
【实现类根据需要重写接口中的默认方法】
4.静态方法
被 public static 修饰; (public可以省略)
【用接口名调用】
5.私有方法
被 private 修饰的方法
【只能在本接口中使用】
方法引用
当一个Lambda表达式所做的事情,可以用一个方法来完成时,可以使用方法引用来代替
- 对象引用方法
public class Calculator {
//求两个数的和
public int add(int a,int b){
return a+b;
}
//求两个数的差
public int sbu(int a,int b){
return a-b;
}
//求两个数的最大值
public int max(int a,int b){
return a>b?a:b;
}
}
public interface HomeWork {
public int doHomeWork(int a,int b);
}
public class Demo6 {
public static void main(String[] args) {
//Lambda表达式(省略数据类型 和{} 以及return语句)
method((a,b)-> a+b);
System.out.println("-----");
//当Lambda表达式所做的事情,可以用一个方法来完成时,就可以使用方法引用
Calculator calculator = new Calculator();
method(calculator::add);
method(calculator::sbu);
method(calculator::max);
}
public static void method(Homework work){
int result = work.doHomework(10, 20);
System.out.println(result);
}
}
- 类名引用实例方法
public interface SubString {
//String类中有一个方法,可以接收两个int类型的参数
//就可以使用String引用这个方法
public String doSubString(String s,int start,int end);
}
public class Demo7 {
public static void main(String[] args) {
method((s, start, end) -> s.substring(start,end));
//类名::方法名
//String表示的是 s的类型
//substring: 接收的是上面的 start和end两个参数
method(String::substring);
}
public static void method(SubString sub){
sub.doSubString("再过一会就要吃饭了",6,9);
}
}
- 引用构造方法
当Lambda表达式的结果是使用构造方法创建的对象时,可以使用引用构造器
public class Student {
private String name;
private int age;
public Student(String name, int age) {
this.name = name;
this.age = age;
}
@Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
}
public interface BuildStudent {
//使用name和age创建一个Student对象并返回
public Student createStudent(String name,int age);
}
public class Demo {
public static void main(String[] args) {
method((name, age) -> new Student(name,age));
//引用构造方法
method(Student::new);
}
public static void method(BuildStudent bs){
Student stu = bs.createStudent("张三", 20);
System.out.println(stu);
}
}