博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Java 8新特性之--lambda表达式的使用和应用
阅读量:2144 次
发布时间:2019-04-30

本文共 3523 字,大约阅读时间需要 11 分钟。

概述

Lambda表达式也可称为闭包,是Java 8的重要更新,也是一个被广大开发者期待已久的新特性。Lambda表达式支持将代码作为方法参数,Lambda表达式允许使用更简洁的代码来创建只有一个抽象方法的接口(这种接口被称为函数式接口)的实例。

 Oracle 公司于 2014 年 3 月 18 日发布 Java 8,Lambda从2014年到2019年已经有5个年头的生命了,可以在实际的项目中的应用其实还是有限的,最主要的原因应该包括以下几个方面:

  • Lambda仅仅是一种语法糖,用命令式编程的方式一样可以达到的效果,再学习的成本过高;
  • 对于新手Javaer来说,刚刚理解到面向对象的精华后,以Lambda的写法简直是在挑战自己的理解力;
  • Lambda的学习定义较抽象,内容较烦杂,应用较凌乱,再加上不清楚应用领域,致使放弃学习。

Lambda使用的目的:

  1. 为了简化(简洁)代码!
  2. 使用Java 8的Stream流式API处理集合。

因为Lambda是甜食,所以理解后,总是能尝到些甜头的,所以大家还是耐心的学习一下Lambda吧。

使用

1.Lambda语法定义

先来看看Lambda的直接使用的例子吧--匿名内部类的替换:

//匿名内部类方式创建线程,启动public void oldRunable() {       Thread t = new Thread(new Runnable() {            @Override            public void run() {                System.out.println("The old runable now is using!");            }        });        t.start();}//lambda方式创建线程,启动public void runable() {       Thread t2 = new Thread(() -> System.out.println("It's a lambda function!"));       t2.start();}

结果显而易见的lambda极大程度的简化了代码,代码的关键技术是创建一个Runnable接口的对象,重写接口里面的run方法,将这个对象传递到Thread的构造器里,让我们看看Lambda简化了什么:

  1. 编译器既然知道Thread的构造器里需要Runnable的对象,所以可以吧new Runnable省了;
  2. Runnable接口只有一个叫run的方法,所以方法名也省了;

lambda就是想尽一切方式简化代码,编译器能推理出来的东西交给机器去处理,程序员只要按照机器认识的方式编写必要出现的代码。

Lambda的语法定义,它由三部分组成

  1. 形参列表。可以省略形参的类型,因为编译器知道接口中方法类型。如果是只有一个参数那么连“()”也可以省;
  2. 剪头(->);
  3. 代码块。如果代码块只有一条语句可以将“{}”省略;如果只有一条return语句,那么“return”可以省略;

例子:来看看最全的写法(String a)-> { return a + "," ;}

简化后的写法:  a -> a + ","           (省了“()”,省了类型,省了return,省了花括号)

自己一定要多练习几个写法,这样再见到各种奇怪的Lambda写法就眼熟了。

至此你已经对Lambda的写法“了如指掌”,接下来要学习另一个新知识。

2.Lambda表达式与函数式接口

其实看了上面的内容对于Lambda的理解除了写法,也起不到别的作用,这里要介绍一个“目标类型(target type)”,

Lambda表达式的目标类型必须是“函数式接口(functional interface)”。函数式接口:只包含一个抽象方法的接口。接口可以包含多个默认方法、类方法,但关键是一个抽象方法。


 Java8 的函数式接口有很多,如:Runnable,ActionListener,Filter,Comparator,新添加的Function,Predicate等,java8专门为函数式接口提供了@FunctionalInterface注解,可以使用此注解编写函数式接口,限制接口编写非函数式接口内容。


说白点就是Lambda表达式是要创建一个接口的对象,对象的类型是只有一个抽象方法的接口,来看看。

​​​​​​​Runnable r = () -> System.out.println("我是java老手");

=号右面的是Lambda表达式,左边的是函数式接口,那么现阶段能使用Lambda的地方一下子就限制住了就给那“几个”接口来用。

哪里使用函数式接口,哪里就有Lambda

3.方法引用与构造器引用(::)

Lambda对比传统写法已经很简洁了,可以你以为上面的写法就是最简洁的了吗?不是。在上面Lambda的的语法定义中,如果Lambda表达式的代码块只有一条代码,还可以再代码块中使用方法引用和构造器引用。

Lambda的使用已经完成了,方法引用只有一点好处就是“简单代码”,不过缺点也明显不易理解和阅读不便,如果你完全不使用方法引用没问题,你所看的所有方法引用都可以换成原始Lambda表达式。

方法引用和构造器引用可以让Lambda表达式的代码在简洁的基础上再简洁,使用::双冒号来使用方法引用,看看有几种引用方式:

下面是一组例子,教你使用方法引用代替Lambda表达式:

    //c1 与 c2 是一样的(静态方法引用)

    Comparator<Integer> c2 = (x, y) -> Integer.compare(x, y);
    Comparator<Integer> c1 = Integer::compare;
    
    //下面两句是一样的(实例方法引用1)
    persons.forEach(e -> System.out.println(e));
    persons.forEach(System.out::println);
    
    //下面两句是一样的(实例方法引用2)
    persons.forEach(person -> person.eat());
    persons.forEach(Person::eat);
    
    //下面两句是一样的(构造器引用)
    strList.stream().map(s -> new Integer(s));
    strList.stream().map(Integer::new);

方法引用虽然精炼到了极致,可是使用时候阅读不易,所以请酌情。。。

4.Lambda表达式可使用的变量和作用域

@Testpublic void test1(){    //将为列表中的字符串添加前缀字符串    String a= "lambda :";    List
proStrs = Arrays.asList(new String[]{"Ni","Hao","Lambda"}); List
execStrs = proStrs.stream().map(b-> { Long c= System.currentTimeMillis(); return a + b+ " -----:" + c; }).collect(Collectors.toList()); execStrs.forEach(System.out::println);}

输出:

lambda :Ni -----:1498722594781lambda :Hao -----:1498722594781lambda :Lambda -----:1498722594781

变量a :外部变量

变量b:传递变量

变量c:内部自定义变量

 lambda表达式可以访问给它传递的变量,访问自己内部定义的变量,同时也能访问它外部的变量。不过lambda表达式访问外部变量有一个非常重要的限制:变量不可变(只是引用不可变,而不是真正的不可变)。

Java中内部类以及Lambda表达式中也不允许修改外部类中的变量。

5.Lambda的应用

说了这么多Lambda表达式,目前使用最多的就是集合框架的应用,本章只是对Lambda语法的使用作介绍,以这章为基础的前提下再学习其应用。

将在下一章中给大家带来Lambda的主要使用场景--Stream流API的使用。

(完)

 

转载地址:http://eqhgf.baihongyu.com/

你可能感兴趣的文章
用 Recursive Neural Networks 得到分析树
查看>>
RNN的高级应用
查看>>
TensorFlow-7-TensorBoard Embedding可视化
查看>>
一个隐马尔科夫模型的应用实例:中文分词
查看>>
轻松看懂机器学习十大常用算法
查看>>
一个框架解决几乎所有机器学习问题
查看>>
特征工程怎么做
查看>>
机器学习算法应用中常用技巧-1
查看>>
机器学习算法应用中常用技巧-2
查看>>
通过一个kaggle实例学习解决机器学习问题
查看>>
决策树的python实现
查看>>
Sklearn 快速入门
查看>>
了解 Sklearn 的数据集
查看>>
用ARIMA模型做需求预测
查看>>
推荐系统
查看>>
TensorFlow-11-策略网络
查看>>
浅谈 GBDT
查看>>
如何选择优化器 optimizer
查看>>
一文了解强化学习
查看>>
CART 分类与回归树
查看>>