函数式编程——Lambda表达式

Lambda表达式

1. Lambda表达式介绍

Lambda 表达式是Java 8引入的重要新特性。Java8中Lambda表达式简化了匿名内部类的形式,并且可以达到同样的效果,使用它设计的代码会更加简洁。通过Lambda表达式,可以替代我们以前经常写的匿名内部类来实现接口。Lambda表达式本质是一个匿名函数。

2. Lambda表达式的使用

interface Cal{
     int add(int a,int b);
}
public class Program {

    public static void main(String[] args) {
        Cal c1=new Cal() {
            @Override
            public int add(int a, int b) {
                return a+b;
            }
        };
       int c=c1.add(1,2);
        System.out.println(c);
    }
}

这个是我们以前的实现,匿名内部类,然后调用执行;
用Lambda表达式改写下:

interface Cal{
    int add(int a,int b);
}
public class test1 {
  public static void main(String[] args) {
       Cal c1=(int a,int b)->{return a+b;};
       int c=c1.add(1, 2);
       System.out.println(c);
       }
}

匿名内部类,直接改成了:

Cal c1=(int a,int b) ->{return a+b;};

3.Lambda表达式语法

(int a,int b) ->{return a+b;};
这个本质是一个函数;
一般的函数类似如下:

int add(int a,int b){
  return a+b;
}

有返回值,方法名,参数列表,方法体

Lambda表达式函数的话,只有参数列表,和方法体;

( 参数列表 ) -> { 方法体 }

说明:

( ) :用来描述参数列表;

{ } : 用来描述方法体;

-> :Lambda运算符,可以叫做箭头符号,或者goes to

总共6种情况,接口方法无返回值有返回值分2种,其中无参数、单个参数多个参数又分3种情况。

package javaMIANXIANGDUIXIANG;
interface If1{
	/* 无参数无返回值 */
	void test();
}
interface If2{
	/* 单个参数无返回值 
	 * @param a
	 * */
	void test(int a);
}
interface If3{
	/* 两个参数无返回值 
	 * @param a,b
	 * */
	void test(int a,int b);
}
interface If4{
	/* 无参数无返回值 */
	int test();
}
interface If5{
	/* 单个参数有返回值 */
	int test(int a);
}
interface If6{
	/* 两个参数有返回值 */
	int test(int a,int b);
}
public class test2 {
	public static void main(String[] args) {
		If1 if1 = ()->{
			System.out.println("无参数无返回值");
	    };
	    if1.test();
	    If2 if2 = (int a)->{
			System.out.println("单个参数无返回值 a="+a);
	    };
	    if2.test(3);
	    If3 if3 = (int a,int b)->{
			System.out.println("两个参数无返回值 c="+a+b);
	    };
	    if3.test(3, 4);
	    If4 if4 = ()->{
			System.out.println("无参数有返回值");
			return 100;
	    };
	    System.out.println(if4.test());
	    If5 if5 = (int a)->{
			System.out.println("单个参数有返回值");
			return a;
	    };
	    System.out.println(if5.test(300));
	    If6 if6 = (int a,int b)->{
			System.out.println("两个参数有返回值");
			return a+b;
	    };
	    System.out.println(if6.test(30, 50));
	}
}


在这里插入图片描述

4. Lambda表达式精简语法

1,参数类型可以省略
2,假如只有一个参数,()括号可以省略

package javaMIANXIANGDUIXIANG;
interface If7{
	int test(int a);
}
public class test1 {
	public static void main(String[] args) {
		If7 if7=a->{return a;};
		System.out.println(if7.test(3));
	}
}

3,如果方法体只有一条语句,{}大括号可以省略

package javaMIANXIANGDUIXIANG;
interface If7{
	void test(int a);
}
public class test1 {
	public static void main(String[] args) {
		If7 if7=a->System.out.println("a="+a);
		if7.test(3);
	}
}

4,如果方法体中唯一的语句是return返回语句,那省略大括号的同事return也要省略

package javaMIANXIANGDUIXIANG;
interface If7{
	int test(int a);
}
public class test1 {
	public static void main(String[] args) {
		If7 if7=a->a;
		System.out.println(if7.test(3));
	}
}

5. 方法引用

适用于多个lambda表达式实现函数是一样的情况,可以封装成通用方法,以便于维护。

语法:
对象::方法
如果是static方法,直接类名::方法

interface If8{
	int program(int a);
}
public class test3 {
	public static void main(String[] args) {
		test3 t=new test3();
		If8 if8=t::program;
		If8 if81=test3::program1;//讲方法都封装到If8接口中
		System.out.println(if8.program(2));
		System.out.println(if81.program(3));
	}
	public int program(int a) {
		return a;
   }
	public static int program1(int a) {
		return a*a;
	}
}

在这里插入图片描述

6. 构造方法的引用

如果函数式接口的实现恰好可以通过调用一个类的构造方法来实现,
那么就可以使用构造方法引用;
语法:类名::new

class Person{
	private String name;
	private int Age;
	public Person() {
		System.out.println("无参构造方法");
	}
	public Person(String name,int age) {
		System.out.println("有参构造方法");
		this.name=name;
		this.Age=age;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name=name;
	}
	public int getAge(int age) {
		return age;
	}
	public void  setAge(int age) {
		this.Age=age;
	}
	public String toString() {
		 return "Person{" +
	                "name='" + name + '\'' +
	                ", age=" + Age +
	                '}';
	}
}
interface PersonService{
	Person getPerson();
}
interface PersonService2{
	Person getPerson(String name,int age);
}
public class test4 {
	public static void main(String[] args) {
		//普通调用构造方法
		PersonService personService=()->new Person();
		personService.getPerson();
		PersonService2 personService2=(String name,int age)->new Person("BOb",18);
		System.out.println(personService2.getPerson(null,0));//由实际创建Person类对象时传入参数,这里的参数没有实际意义
		
		System.out.println();
		//调用类的构造方法实现
		//引用无参构造方法
		PersonService personService3=Person::new;
		personService3.getPerson();
		//引用有参构造方法
		PersonService2 dogService21=Person::new;
		System.out.println(dogService21.getPerson("Alice",19));
		
		
	}
}

PersonServicePersonService2两个接口分别调用了Person类的构造方法。
在主函数先通过普通调用方法,直接利用lambda表达式创建对象的方式调用了Person类中的构造方法,进行了无参和有参构造方法在接口中的实现。
通过 类名::new 的方式直接进行构造方法的引用,有参构造方法在引用后进行传参实现成员变量的赋值操作。

在这里插入图片描述

7. 综合案例

import java.util.List;
import java.util.ArrayList;
class Person1{
	private String name;
	private int Age;
	public Person1(String name,int age) {
		this.name=name;
		this.Age=age;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name=name;
	}
	public int getAge() {
		return Age;
	}
	public void  setAge(int age) {
		this.Age=age;
	}
	public String toString() {
		 return "Person1{" +
	                "name='" + name + '\'' +
	                ", age=" + Age +
	                '}';
	}
}
public class test5 {
	public static void main(String[] args) {
	List<Person1>list=new ArrayList();
	list.add(new Person1("BoB",15));
	list.add(new Person1("Alice",16));
	list.add(new Person1("Smith",16));
	list.add(new Person1("Kitty",8));
	list.add(new Person1("Jerry",25));
	list.add(new Person1("Tom",75));
	list.add(new Person1("Maxima",45));
//	排序
	
	System.out.println("Lambda集合排序:");
	list.sort((o1,o2)->o1.getAge()-o2.getAge());//Lambda表达式重写sort方法Comparator接口中的compareTo方法,由小到大排序
	System.out.println(list);
//  遍历集合
	System.out.println("Lambda集合遍历:");
	list.forEach(System.out::println);
	}
}

查看sort方法中的Comparator接口

在这里插入图片描述
查询Comparetor接口中的compare方法

在这里插入图片描述

在这里插入图片描述
查看一下集合的forEach方法:
在这里插入图片描述
在这里插入图片描述
Consumer接口中有2个方法,有且只有一个声明为accept(T t)的方法,接收一个输入参数并且没有返回值。

8. @Functionallnterface注解

在Consumer接口,Comparator接口都有@Functionallnterface注解。
该注解是函数式接口注解,函数式接口,首先是一个接口,在这个接口中只能有一个抽象方法。
这种类型的接口也称为SAM接口,即Single Abstract Method interfaces。

● 接口有且仅有一个抽象方法
● 允许定义静态方法
● 允许定义默认方法
●允许java.lang.Object中的public方法
● 该注解不是必须的,如果一个接口符合“函数式接口”定义,加不加该备注都没有影响。加上该注解能够更好的让编译器进行检查。如果编写的不是函数式接口,但是加上了@Functionallnterface,编译器会报错。

// 正确的函数式接口
@FunctionalInterface
public interface TestInterface {
 
    // 抽象方法
    public void sub();
 
    // java.lang.Object中的public方法
    public boolean equals(Object var1);
 
    // 默认方法
    public default void defaultMethod(){
    
    }
 
    // 静态方法
    public static void staticMethod(){
 
    }
}

// 错误的函数式接口(有多个抽象方法)
@FunctionalInterface
public interface TestInterface2 {

    void add();
    
    void sub();
}
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

AMBLE RUM

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值