函数式接口
jdk8中新增了函数式接口,在一个接口中 只有一个抽象方法的接口 被称为 函数式 接口,例如
Java.lang.Runnable,java.util.concurrent.Callable。Jdk8中新增了 @FunctionallInterface 注解来标注一个函数式接口。
default方法
jdk8中新增了default方法,jdk8之前接口中的方法 必须都是 抽象的,在jdk8中允许 接口定义 非抽象方法,
在接口中的非抽象方法上使用default修饰即可。jdk8打破了接口中的方法 必须都是 抽象的 这一规范,有一个好处就是 可以提高程序的兼容性。在接口中定义default方法可以变相的让java支持“多继承”。
package Test;
@FunctionalInterface
public interface MyInterface {
void m1(int a,int b);
default String m2(String s) {return null;};
default void m3() {};
}
Lambda表达式格式
可以将lambda看做是一个匿名方法,lambda只能用于函数式接口
(类型 参数,类型 参数,。。。。。,类型 参数)->{ 代码块}
主要由这几个符号构成:
()->{}
Lambda优点:使用Lambda表达式可以编写出 比匿名内部类更简洁的代码
实例:
//不使用Lambda表达式
MyInterface oldType = new MyInterface() { //匿名内部类的方法
@Override
public void m1(int a, int b) {
System.out.println("不使用Lambda方法"+(a+b));
}
};
oldType.m1(10, 20);
//使用Lambda表达式
MyInterface newType = (a,b)->{System.out.println("使用Lambda方法"+(a+b));}; //使用Lambda表达式
newType.m1(20, 30);
使用Lambda表达式在多线程中的写法
//不使用Lambda在多线程中的写法;匿名内部类的写法
Thread t1 = new Thread(new Runnable() {
@Override
public void run() {
for(int i =0;i<1000;i++) {
System.out.println("不使用Lambda表达式的输出 :Helloword");
}
}
});
t1.run();
//使用Lambda表达式在多线程的写法,实现接口即可,重写接口中的地方
//因为Thread类中接收Runnable类型的对象,所以编译器会识别出lambda表达式是Runnable对象
Thread t2 =new Thread( ()->{for(int i =0;i<1000;i++) {
System.out.println("使用Lambda表达式的输出 :HelloWord" );
}});
t2.run();
Lambda表达式为什么只能用于函数式接口
Lambda表达式实际上就是重写了接口中的抽象方法,在函数式接口中只有一个抽象方法,此时编译器会认定重写的就是该唯一的抽象方法。
倘若一个接口中有多个抽象方法,而lambda 表达式 是没有 匿名的,编译器就无法判断 其 重写的是哪个抽象 方法了。
forEach方法
在jdk8中的java.lang.Iterable接口中新增了非抽象的forEach方法。可以使用该方法配合Lambda来遍历集合。
(因为集合继承了该接口)
下面演示使用 forEach方法 遍历集合
ArrayList<Integer> arr = new ArrayList<>();
arr.add(1);
arr.add(2);
arr.add(3);
arr.add(4);
//增强for循环
for(Integer i:arr) {
System.out.println(i);
}
//使用Lambda表达式 forEach写法
arr.forEach(( t)->{System.out.println(t);});
//不使用Lambda表达式 forEach
arr.forEach(new Consumer<Integer>() {
public void accept(Integer t) {
System.out.println(t);
}
});
//Java 8新增方法引用,方法 引用 ::双冒号 操作符 表示
arr.forEach(System.out::print);
方法引用
方法引用主要是用来简写 lambda表达式,有些lambda表达式里面仅仅是执行一个 方法调用,这时使用方法 引用可以简写 Lambda表达式。
Integer[] num = {5,8,13,6,9};
//不使用Lambda表达式
Arrays.sort(num, new Comparator<Integer>() {
public int compare(Integer o1, Integer o2) {
return Integer.compare(o1, o2);
}
});
for(Integer i:num) {
System.out.println(i);}
//使用Lambda表达式
Arrays.sort(num, (o1,o2)->{return Integer.compare(o1, o2);});
for(Integer i:num) {
System.out.println(i);}
//方法引用
Arrays.sort(num,Integer::compare);
一共有四种类型的方法引用:
静态方法引用,类名 ::方法名
某个对象的引用,对象变量名::方法名
特定类的任意对象的方法引用,类名::方法名
构造方法,类名::new