Lambda表达式

一、说明

Lambda表达式是JDK8推出一个重要的新特性,是一种语法糖,其主要目的是可以代替匿名类,简化代码。为了便捷开发,JDK 提供了大量的内置函数式接口供我们使用。

二、语法结构

(parameters) -> expression  
或
(parameters) ->{ statements; }

其中 () 用来描述参数列表,如果参数只有一个可以省略括号,{} 用来描述方法体,单个语句可以省略,-> 为 lambda运算符 ,读作(goes to),parameters表示参数,expression表示表达式,statements表示代码块。

1.表达式举例

()->"hello" //无参数,返回字符串
()->System.out.println("hello")//无参数,无返回值,等价于,可以引用已有的静态函数来代替lambdab表达式,例如 System.out::println("hello")
(a,b)->a+b //不指定参数类型,返回值为a+b
(int a,int b)->{a++; b++;return a+b;}//指定参数类型,多条语句要用代码块

   

三、Lambda demo

JavaBean

public class Lambda {//定义函数式接口
    interface DoubleOpreation{
        int doubleOpreationFunc(int a,int b);
    }
    interface SingleOpreation{
        int  singleOpreationFunc(int a);
    }
    interface TestChongzai{
        default int test(int a){ //default 修饰有默认实现的接口
            a=0;
            System.out.println(a);
            return a;
        }
        void test(String s,String s2);
    }
    interface NullConstructor{
        Dog getNullConstructor();
    }
    interface ParmConstructor{
        Dog getParmConstructor(String name,int age);
    }

    interface Get{
        String getString();
    }
    public static int sub(int a,int b){
        return a-b;
    }
    public int  useDoubleOpreation(int a, int b,DoubleOpreation doubleOpreation){
        return doubleOpreation.doubleOpreationFunc(a,b);
    }
    public int useSingleOpreation(int a,SingleOpreation singleOpreation){
        return singleOpreation.singleOpreationFunc(a);
    }
}


public class Dog {
    private String  name;
    private int age;
    private ArrayList<String> foods;
    private Dog friend;

    public Dog(String name, int age) {
        this.name = name;
        this.age = age;
    }

    public Dog() {
    }

    @Override
    public String toString() {
        return "Dog{" +
                "name='" + name + '\'' +
                ", age=" + age +
                ", foods=" + foods +
                ", friend=" + friend +
                '}';
    }

    public Dog getFriend() {
        return friend;
    }

    public void setFriend(Dog friend) {
        this.friend = friend;
    }

    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 ArrayList<String> getFoods() {
        return foods;
    }

    public void setFoods(ArrayList<String> foods) {
        this.foods = foods;
    }
}

1.基本表达式实现

Lambda lambdaTest = new Lambda();
System.out.println(lambdaTest.useDoubleOpreation(5, 6, (a, b) -> a + b));//lambda表达式里的变量名不能与局部变量名相同
System.out.println(lambdaTest.useDoubleOpreation(5,6,Lambda::sub));
System.out.println(lambdaTest.useDoubleOpreation(5, 6, (int a, int b) -> {
    a += 10;
    b += 10;
    return a * b;
}));
System.out.println(lambdaTest.useSingleOpreation(6, a -> a + 1));
Lambda.Get get = () -> "666";
System.out.println(get.getString());

输出
11
-1
240
7
666

2.注意事项

Lambda表达式可以引用局部变量,但变量不能被修改(修改会报编译错误),相当于隐式final

int c = 2; 
System.out.println(lambdaTest.useSingleOpreation(6, a -> a + c));
输出
8

Lambda表达式只适用于单个抽象方法的接口, 无法实现具有两个抽象方法的接口

Lambda.TestChongzai testChongzai0=(String s1,String s2)-> System.out.println(s1+s2); //TestChongzai只有一个抽象接口,另一个有默认实现,所以还是可以用lambda表达式
testChongzai0.test(1);
testChongzai0.test("a","b");
输出
0
ab

3.主要用途

3.1 用于foreach

List<Integer> list=new ArrayList<Integer>();
list.add(1);
list.add(9);
list.add(9);
list.add(7);
list.add(10);
list.add(18);
list.add(5);
System.out.println("双冒号引用");
list.forEach(System.out::println);//双冒号引用实现遍历集合控制台输出
list.sort((a,b)->a-b);//代替匿名内部类new Comparator
list.removeIf(del->del.equals(5));//lambda表达式遍历集合删除元素
System.out.println("lambda");
list.forEach(n-> System.out.print(n+" "));//lambda表达式实现遍历集合控制台输出
System.out.println();
list.forEach(n-> {if(n<=9) System.out.print(n+" ");});

输出
    
双冒号引用
1
9
9
7
10
18
5
lambda
1 7 9 9 10 18 
1 7 9 9 

3.2 用于代替匿名类

list.sort((a,b)->a-b);//代替匿名内部类new Comparator
new Thread(()->{while(true) System.out.println("Thread-A");}).start();//代替匿名内部类new Runnable
new Thread(()->{while(true) System.out.println("Thread-B");}).start();

Lambda 表达式与匿名类的区别?

(1)使用匿名类与 Lambda 表达式的一大区别在于关键词的使用。

对于匿名类,关键词 this 解读为匿名类,而对于 Lambda 表达式,关键词 this 解读为写就 Lambda 的外部类。

(2)Lambda 表达式与匿名类的另一不同在于两者的编译方法。
Java 编译器编译 Lambda 表达式并将他们转化为类里面的私有函数。

3.3 用于构造方法引用

一般我们需要声明接口,该接口作为对象的生成器,通过 类名::new 的方式来实例化对象,然后调用接口方法来返回对象。

Lambda.NullConstructor constructor1=()->new Dog();
Dog dog1=constructor1.getNullConstructor();
dog1.setName("Dog1");
dog1.setAge(2);
Lambda.ParmConstructor constructor2=Dog::new;
Dog dog2=constructor2.getParmConstructor("Dog2",1);
System.out.println(dog1);
System.out.println(dog2);

输出
Dog{name='Dog1', age=2, foods=null, friend=null}
Dog{name='Dog2', age=1, foods=null, friend=null}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值