Java8 新特性之lambda表达式

函数式接口

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

猜你喜欢

转载自blog.csdn.net/ZHOUJIAN_TANK/article/details/88393315