Lambda表达式的相关知识(概念、简化和用法)

概念

lambda表达式是java8的新特性之一,本质上来说是一个匿名函数,可以简化接口的实现从而简化代码。

使用限定:只有函数式接口才能使用lambda表达式简化实现。

  • 函数式接口:接口中只有一个需要实现的方法的接口就是函数式接口(不包括default修饰的默认的方法,static修饰的静态方法,以及从object继承的toString等方法。)
  • 可以使用@FunctionalInterface注解检验是否是函数式接口
    在写lambda表达式的时候只用关注参数列表和方法体:
(参数)->{方法体}

其中:

  • 参数部分︰方法的参数列表,要求和实现的接口中的方法参数部分一致,包括参数的数量和类型。
  • 方法体部分︰方法的实现部分,如果接口中定义的方法有返回值,则在实现的时候,注意返回值的返回。
  • ->:分隔参数部分和方法体部分。
    精简策略:

精简表达式

可以省略表达式的参数类型

  • 如果接口方法参数只有一个,可以省略lambda表达式的小括号。
    如:
//函数接口
public interface MyTest{
	void test(int a);
}
//lambda表达式
MyTest myTest = a->{System.out.println(a);};
//调用方法
myTest.test();
  • 如果接口方法方法体只有一个语句,可以省略大括号。
//函数接口
public interface MyTest{
	void test(int a);
}
//lambda表达式
MyTest myTest = a->System.out.println(a);
//调用方法
myTest.test(a);

  • 如果接口方法方法体有返回值,则lambda表达式中要有返回值。
//函数接口
public interface MyTest{
    //有返回值的方法
	int test(int a);
}
***********************************************************

//lambda表达式
MyTest myTest = a->{
System.out.println(a);
return a;
};
***********************************************************

//调用方法
myTest.test(a);

  • 如果接口方法方法体只有一个语句,并且有返回值,则省略大括号的同时需要把return也省略,否则错误。
//函数接口
public interface MyTest{
	int test(int a);
}
***********************************************************

//lambda表达式
MyTest myTest = a->a*a; //等价于a->{return a*a;};
***********************************************************

//调用方法
myTest.test(a);

函数引用:

为了继续简化太过复杂的逻辑的代码,可以调用其他地方已经实现的方法来实现函数接口,这种方式称为函数引用。存在以下情况:

  1. 静态方法引用:类::静态方法,方法名后不要添加小括号,并且方法的参数和返回值必须和接口的一样
//某个类,其中存在静态方法
public class Demo{
    //静态方法
	public static void out(){
		System.out.println("这是静态方法");
	}
}
***********************************************************
//函数式接口
public interface MyTest{
	void testMethod();
}
***********************************************************
//使用lambda表达式
MyTest myTest = Demo::out; //等价于 ()->{Demo.out();}
***********************************************************
//调用方法
myTest.testMethod();
  1. 非静态方法引用:对象::非静态方法名,如果对象没有实例化就要new一个对象,即new 对象::方法名
//某个类,其中存在静态方法
public class Demo{
    //非静态方法
	public void out(){
		System.out.println("这是静态方法");
	}
}
***********************************************************

//函数式接口
public interface MyTest{
	void testMethod();
}
***********************************************************

//使用lambda表达式
MyTest myTest = new Demo()::out; //等价于 ()->{Demo.out();}
***********************************************************

//调用方法
myTest.testMethod();
  1. 构造方法的引用:类名::new,无论无参、有参构造方法,都是用这个方式,使用时会自动匹配构造方法,并且可以通过接口中的方法的参数,区分引用的构造方法。(某个接口定义的方法仅仅是为了得到一个类的对象,就可以使用这种方法)
   //带三种构造方法的Person类
	private static class Person {
		String name;
		int age;
		public Person() {
				System.out.println("Person类的无参构造方法执行了");
			}
		public Person(String name) {
				this.name = name;
				System.out.println("Person类的有参构造方法执行了");
			}
		public Person(String name,int age) {
				this.name = name;
				this.age = age;
				System.out.println("Person类的两个参数的构造方法执行中);
			}
**********************************************************
    //无参构造函数式接口
  public interface MyTest1{
  			Person getNullParameter();
  }
    //一个参数构造函数式接口
  public interface MyTest2{
  			Person getSingleParameter(String name);
  }
   //两个参数构造函数式接口
  public interface MyTest3{
  			Person getDoubleParameter(String name,int age);
  }
***********************************************************
   //使用lambda表达式
   //无参
   MyTest1 myTest1 = Person::new;
   //一个参数
   MyTest1 myTest1 = Person::new;
   //两个参数
   MyTest1 myTest1 = Person::new;
   //调用接口的方法
   //无参
   myTest1.getNullParameter();
   //一个参数
   myTest2.getSingleParameter("myName");
   //两个参数
   myTest3.getDoubleParameter("myName",19);
  1. 对象方法的特殊引用:如果在使用lambda表达式,实现某些接口的时候。lambda表达式中包含了某一个对象,此时方法体中,直接使用这个对象调用它的某一个方法就可以完成整体的逻辑。其他的参数,可以作为调用对象的方法的参数。此时,可以对这种实现进行简化。表达式:对象名::方法名,然后利用接口.方法(参数)即可。
    如:
	//某个对象的类
 	public  class Person {		
		private String name ;
		public void setName(String name) {
			this.name = name;
		}
		public String getName() {
			return name;
		}
	}

 	//函数式接口
 	public interface MyTest{
 		String get(Person person);
 	}
 
   //使用lambda表达式
   Person person = new Person(); //创建一个person对象
   person.setName("zhangsan");
   MyTest myTest = Person::getName; //等价于 MyTest myTest = (p)->{p.getName;};

注:lambda表达式中如果用到局部变量,则该局部变量会自动变为常量,不能在后面再做修改,如果是全局变量则没有问题

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值