技术交流


JAVA——lambda表达式

Apr 27, 2019 8:13:50 PM
210
1

lambda表达式是java8的新特性。

为什么使用Lambda

Lambda是一个可传递的代码块,可以在以后传递一次或多次。Lambda可是对一个接口进行快速实现。

使用lambda表达式实现接口注意

接口必须是一个函数式接口(只有一个抽象方法需要实现的接口)。设计自己的lambda函数式接口可以在接口上加注解@FunctionInterface

lambda基本语法

():写参数列表。

->goes to参数方法连接符。

{}:写方法体。

简单的例子

1、先定义接口

@FunctionalInterface
public interface LambdaBase {
    int add(int a, int b);
}

2、测试代码

public class LambdaBaseTest {
    public static void main(String[] args) {
        //lambda表达式
        LambdaBase lambdaBase = (a, b) -> {
            return a + b;
        };
        //输出结果
        System.out.println(lambdaBase.add(10, 20));
    }
}

3、输出结果为30

lambda语法简化

1、准备接口

@FunctionalInterface
public interface LambdaBase {
    int add(int a, int b);
}

@FunctionalInterface
public interface LambdaOneParamNoReturn {
    void test(String a);
}

2、测试代码

public class JianHua {
    public static void main(String[] args) {
        //1、参数只有一个可省略小括号
        LambdaOneParamNoReturn lambdaOneParamNoReturn = a -> {
            System.out.println("输出" + a);
        };
        lambdaOneParamNoReturn.test("apple");

        //2、如果方法体只有一句,可以省略大括号
        LambdaOneParamNoReturn lambdaOneParamNoReturn1 = a -> System.out.println("输出" + a);
        lambdaOneParamNoReturn1.test("abc");

        //3、如果方法体的唯一一句是返回语句,在省略大括号的同时要省略return关键字
        LambdaBase lambdaBase = (a, b) -> a + b;
        System.out.println(lambdaBase.add(1, 2));
    }
}

方法引用

lambda方法引用是lambda指向的是一个具体的方法。

语法:方法隶属者::方法名。(方法隶属者是对象名或类名)。

注意:方法的参数列表、返回值必须与接口完全一样。

示例如下

1、接口

@FunctionalInterface
public interface LambdaBase {
    int add(int a, int b);
}

2、测试

public class FangFaYinYong {
    public static void main(String[] args) {
        LambdaBase lambdaBase = FangFaYinYong::add;
        System.out.println(lambdaBase.add(1, 2));
    }

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

输出结果3

构造器引用

语法:构造的对象::new

示例

1、对象

public class Student {

    private String name;

    private Integer age;


    public Student() {
        System.out.println("无参构造器执行了");
    }

    public Student(String name, Integer age) {
        this.name = name;
        this.age = age;
        System.out.println("有参构造器执行了");
    }
}

 

2、接口

/**
 * 无参数接口
 */
@FunctionalInterface
public interface StudentNoParamConstruct {
    Student getStudent();
}

/**
 * 有参接口
 */
@FunctionalInterface
public interface StudentHaveParamConstruct {
    Student getStudent(String name, int age);
}

3、测试

public class ConstructorTest {
    public static void main(String[] args) {
        //无参构造器引用
        StudentNoParamConstruct studentNoParamConstruct = Student::new;
        studentNoParamConstruct.getStudent();

        //有参构造器引用
        StudentHaveParamConstruct studentHaveParamConstruct = Student::new;
        studentHaveParamConstruct.getStudent("jack", 20);
    }
}

打印结果:

无参构造器执行了

有参构造器执行了

forEach遍历集合

语法:集合.forEach(lambda表达式)

示例

public static void main(String[] args) {
    List<Integer> list = new ArrayList<>();
    Collections.addAll(list, 1, 2, 3, 4, 5, 6);

    //打印集合元素
    list.forEach(System.out::println);

    //处理集合元素(输出大于5的元素)
    list.forEach(ele -> {
        if (ele > 5) {
            System.out.println(ele);
        }
    });
}

removeIf

作用:删除集合中符合条件的元素。

示例

public static void main(String[] args) {
    List<Integer> list = new ArrayList<>();
    Collections.addAll(list, 1, 2, 3, 4, 5, 6);

    //删除奇数
    list.removeIf(elt -> elt % 2 != 0);
    System.out.println(list);
}

打印结果:[2, 4, 6]

线程实现

示例

public static void main(String[] args) {
    //用lambda实例化线程
    java.lang.Thread thread = new java.lang.Thread(() -> {
        for (int i = 0; i < 10; i++) {
            System.out.println(i);
        }
    });
    thread.start();
}

java常用函数式接口

java常用函数式接口参考:https://www.runoob.com/java/java8-functional-interfaces.html

闭包

闭包会提升包围变量的生命周期(在方法结束后变量不会销毁)。

在使用lambda表达式时,在闭包中引用的变量一定是常量,举例说明:

public static void main(String[] args) {
    int a = 5;
    Consumer<Integer> consumer = elt ->
        System.out.println(a++); //a++编译出错:Variable used in lambda expression should be final or effectively final
    consumer.accept(1);
}

原因:只要在闭包中使用了某个局部变量值,就会将这个局部变量用final修饰,变量值不可更改。像上面这个例子变量a在编译时会以final int a = 5来编译。



如果你喜欢我的内容,就请打赏一下吧
微信
支付宝
温馨提示: 你的打赏金额会直接转入对方账户,不可退回。

评论专区


审核通过的评论(1)
admn
Jul 2, 2019 3:14:15 PM

6a 

个人名片

  欢迎来到“浩瀚星尘”的个人博客!
  首先,该博客用于分享本人的生活事迹与兴趣爱好; 此外,该博客的主要作用便是与广大的小伙伴一起分享探讨开发技术, 希望大家多多关照。

网名: 浩瀚星尘
城市: 重庆
工作: java