Lambda表达式的基础知识(一)

Lambda表达式简介:

一、什么是Lambda表达式?

  • Lambda表达式也被称为箭头函数、匿名函数、闭包
  • Lambda表达式提现的是轻量级函数式编程思想
  • ‘->’ 符号是Lambda表达式核心操作符号,符号左侧是操作参数,符号右侧是操作表达式
  • Lambda表达式时JDK8的新特性

二、为什么要用Lambda表达式

  • 它不是解决未知问题的新技术
  • 对现有解决方案的语义化优化
  • 需要根据实际需求考虑性能问题

 

Lambda表达式基础知识:

一、函数式接口(function interface)的特性

  • 函数式接口是Java类型系统中的接口
  • 函数式接口是只包含一个抽象接口方法的特殊接口
  • JDK8提供的语义化检测注解:@FunctionalInterface

二、在函数式接口中允许存在的方法,并且不影响其特性。有如下3种:

  • 默认(default)接口方法:给所有的实现了接口的对象,增加的通用方法,必须有具体的实现。
  • 静态(static)接口方法:必须有具体的实现。
  • 继承自Object类的方法,不论是具体还是抽象方法。

三、函数式接口与Lambda表达式的联系

  • 函数式接口,只包含一个抽象方法;Lambda表达式,只能操作一个方法。
  • Java中的Lambda表达式,核心就是一个函数式接口的实现。

四、函数式接口的实现可以有三种方式

  1. 创建一个接口的实现类;   (最常见)
  2. 匿名内部类实现接口;      (灵活,冗余)
  3. Lambda表达式实现接口。(灵活,简洁)

第1种最为常见,就不列举了,只对比2,3两种情况:

@FunctionalInterface
public interface IUserCredential {

    /**
     *
     * @param username 用户名
     * @return 验证结果
     */
    String verifyUser(String username);
}


public class App 
{
    public static void main( String[] args )
    {
        //匿名内部类实现接口
        IUserCredential iuc1 = new IUserCredential() {
            @Override
            public String verifyUser(String username) {
                return username.equals("admin")?"系统管理员":"普通用户";
            }
        };
        System.out.println(iuc1.verifyUser("admin"));
        System.out.println(iuc1.verifyUser("user"));


        //Lambda表达式实现接口
        IUserCredential iuc2 = (String username)->{                //此处的String声明可以省略,因为Lambda表达式会自动进行类型检查
            return username.equals("admin")?"系统管理员":"普通用户";
        };
        System.out.println(iuc2.verifyUser("admin"));
        System.out.println(iuc2.verifyUser("user"));

    }
}

五、Lambda表达式基本语法

  1. 声明:就是和Lambda表达式绑定的接口类型
  2. 参数:包含在一对圆括号中,和绑定的接口中的抽象方法中的参数个数及顺序一致。(参数的类型可以不用指定,jvm在运行时,会自动根据绑定的抽象方法中的参数自动推导)
  3. 操作符:->
  4. 执行代码块:包含在一对大括号中,出现在操作符号的右侧。(如果代码块中只有一行,此时大括号可以省略且return关键字也可以省略;如果有多行,或者添加了大括号,必须通过return关键字进行返回)

六、匿名内部类与Lambda表达式的区别

       语法冗余:

 //1.传统模式下,新线程的创建
        new Thread(new Runnable() {
            @Override
            public void run() {
                System.out.println("CurrentThreadId......"+Thread.currentThread().getId());
            }
        }).start();

 //2.使用Lambda表达式创建新线程
        new Thread(()->{
                            System.out.println("CurrentThreadId......"+Thread.currentThread().getId());
                }).start();

       this关键字混淆:Lambda表达式中的变量操作优化了匿名内部类中的this关键字,不再单独建立对象作用域,表达式本身就是所属对象的一部分。

public class App2 {
    String s1 = "全局变量";

    // 1. 匿名内部类型中对于变量的访问
    public void testInnerClass() {
        String s2 = "局部变量";

        new Thread(new Runnable() {
            String s3 = "内部变量";
            @Override
            public void run() {
                // 访问全局变量
//                System.out.println(this.s1);// this关键字~表示是当前内部类型的对象
                System.out.println(s1);

                System.out.println(s2);// 局部变量的访问,~不能对局部变量进行数据的修改[final]
//                s2 = "hello";

                System.out.println(s3);
                System.out.println(this.s3);

            }
        }).start();
    }

    // 2. lambda表达式变量捕获
    public void testLambda() {
        String s2 = "局部变量lambda";

        new Thread(() -> {
            String s3 = "内部变量lambda";

            // 访问全局变量
            System.out.println(this.s1);// this关键字,表示的就是所属方法所在类型的对象
            // 访问局部变量
            System.out.println(s2);
//            s2 = "hello";// 不能进行数据修改,默认推导变量的修饰符:final
            System.out.println(s3);
            s3 = "labmda 内部变量直接修改";
            System.out.println(s3);
        }).start();
    }

    public static void main(String[] args) {
        App2 app = new App2();
        app.testInnerClass();
        app.testLambda();

    }
}

七、JDK8中常见的内置函数式接口

      JDK8提供了java.util.function包,提供了常用的函数式功能接口。例如:

  • java.util.function.Predicate<T>--------接收参数对象T,返回一个boolean类型结果
 Predicate<String> pre = (String username)->{
            return "admin".equals(username);
        };
 System.out.println(pre.test("admin"));
 System.out.println(pre.test("admir"));
  • java.util.function.Consumer<T>--------接收参数对象T,不返回结果
 Consumer<String> con = (String message)->{
            System.out.println("需要打印的消息:" + message);
        };
 con.accept("hello world");
  • java.util.function.Function<T,R>--------接收参数对象T,返回结果对象R
 Function<String ,Integer> fun = (String gender)->{
            return "male".equals(gender)?1:0;
        };
 System.out.println(fun.apply("male"));
 System.out.println(fun.apply("female"));
  • java.util.function.Supplier<T>--------不接收参数,提供T对象的创建工厂,直接通过get()获取指定类型的对象
 Supplier<String> sup = ()->{
            return UUID.randomUUID().toString();
        };
 System.out.println(sup.get());
 System.out.println(sup.get());
  • java.util.function.UnaryOperator<T>--------接收参数对象T,执行业务处理后,返回更新后的T对象
UnaryOperator<String> un = (String str)->{
            return str.toUpperCase();
        };
 System.out.println(un.apply("jijfshdfiUP"));
  • java.util.function.BinaryOperator<T>--------接收两个T对象,执行业务处理后,返回一个T对象结果
 BinaryOperator<Integer> bi = (Integer a,Integer b)->{
            return a>b?a:b;
        };
 System.out.println(bi.apply(5,7));

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值