Java之Lambda表达式

 

        下面来说一下Lambda表达式,这个是 Java 8 的新特性,实质上是简便了对接口的实现,不用再写匿名内部类,而是简单的表达式。

        首先,Lambda只能用于函数式接口,什么是函数式接口?

            定义:抽象方法 的个数只有一个的接口。

就是这个  上边会有一个 @FunctionInterface标识,和@Override一样。

@Override 标识的方法如果不是重写的方法,编译器就会报错。

那@FunctionInterface标识的接口呢,如果接口方法大于一个,也会报错。

 

语法格式是什么样呢?

         (参数列表)->{方法实现语句};

或者  (参数列表)->返回值语句;

从这个结构你就能看出来了,如果 有{} 那就可以多条语句,没有的话 只能有一条语句

下面 来个一Demo  

package day12;
/**示例:Lambda语法*/
@FunctionalInterface
interface Info{
	//1.无参无返回值类型
//	void af();
	//2.有参无返回值类型
//	void af(int n);
	//3.无参有返回值类型
//	int af();
	//4.有参有返回值类型
	int af(int n);
}
public class TestLambda1 {
	//1.无参无返回值类型
/*	Info info1 = ()->{System.out.println("af");};
	//只有一行代码 可以省略{}
	Info info2 = ()->System.out.println("af");*/
	//2 有参无返回值类型
//	Info info3 = (num)->{System.out.println(num);};
//	Info info3 = num ->System.out.println(num);
	//3.无参有返回值类型
//	Info info4 = ()->{return 22;};
//	Info info5 = ()->22;
	//4有参有返回值类型
	Info info6 = (n)->{return n;};
	Info info7 = n->45;
	
	public static void main(String[] args) {
//		new TestLambda1().info3.af(155);
		
		
//		InfoImpl info = new InfoImpl();
//		info.af();
		//2.匿名内部类的实现
/*		new Info() {
			public void af() {
				System.out.println("af");
			}
		}.af();*/

	}

}
/*//1. 定义一个 实现类
class InfoImpl implements Info{
	@Override
	public void af() {
		System.out.println("af");
	}	
}*/

从上边可以看出,其实Lambda表达式 就是为了简写 匿名内部类。

那来比较一下匿名内部类和 Lambda的区别:


1.Lambda只能实现 函数式 接口;
  匿名内部类 可以是继承一个父类 或 实现一个父接口;
2.Lambda只能 针对 函数式接口 中的抽象方法;
  匿名内部类可以 调用 非抽象方法:如:默认方法等。

 

再来个Demo 体会一下

package day12;
//跑
interface Run{
	void run();
}
/*class Dog implements Run{
	public void run() {
		System.out.println("小狗跑了");
	}
}
class Cat implements Run{
	public void run() {
		System.out.println("小猫跑了");
	}
}*/
class ManagerRun{
	//测试 怎么跑的
	public void checkRun(Run run) {
		run.run();
	}
}
public class TestLambda2 {
	public static void main(String[] args) {
		ManagerRun m = new ManagerRun();
		//匿名内部类传参
		m.checkRun(new Run() {	
			@Override
			public void run() {
				System.out.println("小狗跑了");
			}
		});
		//Lambda传参
		m.checkRun(()->{System.out.println("小狗跑了");});
		//Lambda 函数式接口类型
		Run run = ()->{System.out.println("小狗跑了");};
		Object o = run;
		Object o1 =(Run) ()->{System.out.println("小狗跑了");};
		
	/*	Dog dog = new Dog();
		Cat cat = new Cat();
		ManagerRun m = new ManagerRun();
		m.checkRun(dog);
		m.checkRun(cat);*/

	}

}

可以看到Lambda 是多么的灵巧,还有一些对集合操作的 用到Lambda 会非常的方便。

下面再说几种 Lambda的用法 :

Lambda的方法引用

当 Lambda只有一行代码,只调用了一个方法。
 四种形式:
    1.引用类方法;
         类名::类方法
    2.引用特定对象 的 实例方法;
         特定对象::实例方法
    3.引用 某个类对象 的 实例方法;
         类::实例方法
    4.引用 构造器。
         类::new

下面上一个Demo

package day12;
/**示例:方法引用*/
interface La{
	Integer f(String s);
}

class Student{
	private String name;
	Student(String name){
		this.name = name;
	}
}
interface La1{
	Student f(String name);
}
public class TestLambda4 {
	//------------------方法引用----------------------------
	//1.引用 类方法
//	La la1 = s->{return Integer.parseInt(s);};
	La la1 = s -> Integer.parseInt(s);
	La la2 = Integer::parseInt;
	//2.特定对象 引用 实例方法
	La la3 = s->"hello".indexOf(s);
	La la4 = "hello"::indexOf;
	//3.某类对象 的实例方法
	La la5 = s->s.length();
	La la6 = String::length;
	//4.引用构造器
	La1 la7 = s->new Student(s);
	La1 la8 = Student::new;
	
	public static void main(String[] args) {
		Integer i = new TestLambda4().la2.f("35");
		System.out.println(i);
	}

}

 

再上两个Demo

package day12;

import java.util.Arrays;
import java.util.function.IntBinaryOperator;
import java.util.function.IntConsumer;
import java.util.function.IntUnaryOperator;

public class TestLambda5 {

	public static void main(String[] args) {
		int [] arr = {1,2,3,4,5};
		//用 索引 替换掉 数组中的元素
		//一元运算
/*		Arrays.parallelSetAll(arr, new IntUnaryOperator() {
			
			@Override
			public int applyAsInt(int operand) {
				// 数组的索引
				return operand;
			}
		});*/
	
//		Arrays.parallelSetAll(arr,index->index );
		System.out.println(Arrays.toString(arr));
		//二元运算
		//用 二元运算的结果 来替换掉数组的每一个元素
	/*	Arrays.parallelPrefix(arr, new IntBinaryOperator() {
			//     left -前一个元素     right:当前元素
			@Override
			public int applyAsInt(int left, int right) {
				// 当前元素是第一个元素  ,前一个元素  是1
				return left * right;
			}
		});*/
		Arrays.parallelPrefix(arr,(n1,n2)->n1*n2 );
		System.out.println(Arrays.toString(arr));
		//遍历数组 Stream流的方法
		Arrays.stream(arr).forEach(new IntConsumer() {
			//value数组元素
			@Override
			public void accept(int value) {
				System.out.println(value);
			}
		});
		//Lambda
		Arrays.stream(arr).forEach(num->System.out.println(num));
		//方法引用
		Arrays.stream(arr).forEach(System.out::println);

	}

}

 

package day12;
/**练习:Lambda参数传递*/
interface InfoArray{
	void reverse(int[] arr);
}
class ArrayImpl{
	public void display(int [] arr,InfoArray info) {
		info.reverse(arr);
	}
}
public class TestLambda6 {
	public static void main(String[] args) {
		ArrayImpl a = new ArrayImpl();
		int [] arr = {11,22,33,44,55};
		//匿名内部类
		a.display(arr, new InfoArray() {
			
			@Override
			public void reverse(int[] arr) {
				for(int i = arr.length-1; i >=0; i--) {
					System.out.println(arr[i]);
				}
			}
		});
		//Lambda
		a.display(arr, arr1->{
			for(int i = arr1.length-1; i >=0; i--) {
					System.out.println(arr1[i]);
				}
		});

	}

}

 

 

 

写到这里,应该能掌握这个表达式的用法了,要写Lambda表达式,首先也是必须要知道接口的方法是如何实现的,另外呢 Lambda表达式最好用在用的多的地方,就比如遍历集合?!  大家能认出来,否则,这个表达式可读性太差了,所以能不用还是别用  

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值