文章目录

  • 常规写法
    • 写法一:新建类并实现该接口
    • 写法二:使用匿名函数
  • lambda写法
    • 写法一:lambda常规写法
    • 写法二:lambda简写
    • 中场疑问
  • lambda的方法引用
    • 写法一
    • 写法二
  • 练习题
    • 1. 将集合按照指定属性进行排序
    • 2. 将`list.forEach`方法改造成lambda方式
    • 3.删除集合中指定元素
  • 答案

随着Java语言的不断发展,Java8提供的新特性lambda表达式也成为越来越多开发者喜欢的写法,为了顺应时代的变化,需要好好地学习这种写法,并应用在平时的开发中。我们先从简单的例子着手,一步步的深入到lambda的复杂写法,首先我们的任务是创建一个用来比较两个int值大小的接口,并给它添加具体的实现方法,然后进行调用。接口定义如下:

interface Comparator{int compare(int a,int b);
}

常规写法

写法一:新建类并实现该接口

创建MyComparator.java并实现Comparator接口:

class MyComparator implements Comparator{@Overridepublic int compare(int a, int b) {return a > b ? a : b; //输出最大的值}
}

然后进行调用:

public static void main(String[] args) {Comparator comparator = new MyComparator();int res = comparator.compare(1, 10);System.out.println(res);
}

写法二:使用匿名函数

直接new接口

public static void main(String[] args) {//使用匿名方法实现Comparator comparator = new Comparator() {@Overridepublic int compare(int a, int b) {return a > b ? a : b;}};int res = comparator.compare(1, 10);System.out.println(res);
}

lambda写法

跟上面的常规写法不同的是,lambda只关注方法的入参方法体中具体实现的逻辑,其余能省的代码全部都可以省略,我们先看一下第一种写法:

写法一:lambda常规写法

自己比较一下跟匿名函数写法的差别,是不是非常的简洁,lambda只声明了入参方法体内的逻辑,关键地方在于入参和方法体之间使用了->箭头符号进行连接,箭头符号读作gose to

public static void main(String[] args) {//简单的lambda写法Comparator comparator = (int a,int b) -> {return a > b ? a : b;};int res = comparator.compare(1, 10);System.out.println(res);
}

到这里你应该有一个基本的印象了,这一步转变非常重要,停下来好好思考一下。

写法二:lambda简写

仔细观察可以发现写法一中仍然有多余的代码,比如说我们在之前的接口中已经声明过一次入参的类型,在使用的时候又声明了一次,这显然是多余的写法。其实上面的写法依然可以更简洁,只要满足下面这几点,都可以省略。

  1. 当入参类型和初始定义类型一致时,可以省略入参类型。
  2. 当方法体中只有一句代码时,可以省略大括号。
  3. 当方法体中只有一句代码,并且需要返回值时,可以省略return关键字。

更简单的写法如下:

public static void main(String[] args) {//省略了入参类型、大括号、return关键字Comparator comparator = (a,b) -> a > b ? a : b;int res = comparator.compare(1, 10);System.out.println(res);
}

中场疑问

上面我们定义的接口只有一个抽象方法compare(),有的同学就会有疑问,那如果有多个抽象方法怎么写呢?问的很好!由于lambda的写法非常的简洁,但这是在一定的条件限制下才能这么写,其中非常重要的一点就是,只有一个抽象方法的接口才支持lambda的写法,这种接口被称为函数式接口,可以通过@FunctionalInterface注解进行修饰。

@FunctionalInterface只修饰函数式接口,即只有一个抽象方法的接口。

lambda的方法引用

写法一

lambda表达式中方法体只有一行代码才能有最简单的写法,那如果我想写一些复杂的业务就不能简写了吗?其实并不是的,这时候我们就可以泳道lambda的方法引用,将较复杂的业务封装成方法,然后在lambda中进行调用,假如还是上面的例子,我们可以将方法体中的那一行代码封装成一个方法:

public static int max(int a,int b){//这里可以写一些较为复杂的业务return a > b ? a : b;
}

这时候lambda表达式就可以这么写:

public static void main(String[] args) {//方法体中引用max函数Comparator comparator = (a,b) -> max(a,b);int res = comparator.compare(1, 10);System.out.println(res);
}

上面就是一个普通的lambda方法引用,简单的说就是将方法体中的代码封装成一个一方法,然后在调用这个方法即可,需要注意的是max函数中的返回值必须要跟接口中的抽象方法一致,否则就会报异常。

写法二

上面的写法虽然简单有效,但依然有多余的地方,那就是方法参数重复了,代码(a,b) -> max(a,b);中出现了两次(a,b),在实际开发中,我们一般采用另一种写法来代替->箭头符号,请大家牢记语法:

方法的隶属者::方法名。

隶属者可以理解为,能够调用这个方法的对象,如果该方法是static修饰的,则隶属者位当前类;如果不是static修饰的,则隶属者属于一个对象。如果听不懂也没关系,看一个栗子就清晰明了。

首先看一下完整的代码:

//定义接口
interface Comparator {int compare(int a, int b);
}public class Program {public static void main(String[] args) {//使用lambda的方法引用调用max方法,隶属者为类Comparator comparator = Program::max;int res = comparator.compare(1, 10);System.out.println(res);}//用static修饰的方法public static int max(int a,int b){return a > b ? a : b;}
}

从上面代码中我们发现,将之前的(a,b) -> max(a,b);写成了Program::max;,因为方法max被关键字static修饰了,因此隶属者应该是Program这个类。也可以发现省略了参数(a,b),这么写就已经是非常的简洁了,但这么写需要满足两个基本条件:

  1. 只有接口中抽象方法的参数格式跟定义的方法参数格式一样,才能省略参数。
  2. 接口中抽象方法的返回值必须跟定义的方法的返回值一样。

这就是java8引入的新特性,一切为了简洁明了。

方法不是static怎么写?

理解了上面,这个就比较好懂了,贴一下代码,不做解释了

public class Program {public static void main(String[] args) {//创建一个Program对象Program p = new Program();//使用lambda的方法引用调用max方法,隶属者为对象Comparator comparator = p::max;int res = comparator.compare(1, 10);System.out.println(res);}//没有被static修饰的方法public int max(int a,int b){return a > b ? a : b;}
}

练习题

素材如下:

Person.java

class Person{String name ;int 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;}@Overridepublic String toString() {return "Person{" +"name='" + name + '\'' +", age=" + age +'}';}
}

准备集合

public class Program {public static void main(String[] args) {List<Person> list = new ArrayList<>();list.add(new Person("张三",18));list.add(new Person("李四",30));list.add(new Person("王五",16));list.add(new Person("赵六",20));list.add(new Person("田七",40));list.add(new Person("马八",25));        printList(list);}//打印集合public static void printList(List<Person> list){for (Person person : list) {System.out.println(person);}}
}

1. 将集合按照指定属性进行排序

按照person的年龄进行从低到高排序

普通的排序方式:

//使用正常的方式排序
list.sort(new Comparator<Person>() {@Overridepublic int compare(Person o1, Person o2) {return o1.getAge() - o2.getAge();}
});

问题:你能将普通的排序方式改造成lambda的方式吗?写出来后思考还有其他写法吗?

2. 将list.forEach方法改造成lambda方式

正常的list遍历:

list.forEach(new Consumer<Person>() {@Overridepublic void accept(Person person) {System.out.println(person.toString());}
});

问题:如何改造成lambda的方式??改造之后修改练习1中的遍历代码

3.删除集合中指定元素

删除年龄大于35的人

正常的删除:

list.removeIf(new Predicate<Person>() {@Overridepublic boolean test(Person person) {return person.age > 35;}
});

问题:如何改造成lambda的方式??

答案

  1. 排序(二选一)
list.sort((p1,p2) -> p1.getAge() - p2.getAge());
Collections.sort(list,(p1,p2) -> p1.getAge() - p2.getAge());
  1. 遍历
list.forEach(person -> System.out.println(person.toString()));
  1. 删除指定元素
list.removeIf(person -> person.age > 35);

java新特性lambda表达式快速入门相关推荐

  1. Java 8 新特性 lambda表达式

    / Created by Manager on 2021/4/1. Java 8 新特性 lambda表达式 StreamAPI 新日期 新注解 */ 视频连接 1https://www.bilibi ...

  2. java lambda表达式详解_Java8新特性Lambda表达式详解

    课程目标: 通过本课程的学习,详细掌握Java8新特性之Lambda表达式: 适用人群:有Java基础的开发人员: 课程概述:从Java 8出现以来lambda是最重要的特性之一,它可以让我们用简洁流 ...

  3. Java 8 新特性Lambda 表达式

    Java 8 新特性Lambda 表达式 一.常用循环 二.匿名内部类 三.排序集合 四.循环打印对象 五.根据条件修改 六.排序 七.求和 八.统计方法 九.材料 一.常用循环 public cla ...

  4. Java8新特性----Lambda表达式详细探讨

    Java8新特性 Lambda表达式 入门演示 案例1 如何解决 cannot be cast to java.lang.Comparable问题? 案例2 优化方式一 : 策略设计模式 优化方式二: ...

  5. C++11新特性——λ(lambda)表达式详解

    C++11新特性--λ(lambda)表达式 C++11中引入了λ表达式,它可以用来定义一个内联(inline)的函数,作为一个本地的对象或者一个参数.有了λ表达式,我们可以很方便的使用stl标准库. ...

  6. JDK1.8新特性Lambda表达式入门

    摘要:此篇文章主要介绍 Java8 Lambda 表达式产生的背景和用法,以及 Lambda 表达式与匿名类的不同等.本文系 OneAPM 工程师编译整理. Java 是一流的面向对象语言,除了部分简 ...

  7. java8新特性lambda表达式、函数式编程、方法引用和接口默认方法以及内部类访问外部变量

    一提到java是一种什么语言? 大多数人肯定异口同声的说是一门面向对象的语言,这种观点从我们开始学java就已经根深蒂固了,但是学到java8新特性函数式编程的时候,我才知道java并不是纯面向对象的 ...

  8. java8新特性-lambda表达式入门学习

    定义 jdk8发布新特性中,lambda是一大亮点之一.lambda表达式能够简化我们对数据的操作,减少代码量,大大提升我们的开发效率.Lambda 表达式"(lambda expressi ...

  9. 【Java】jdk 1.8 新特性——Lambda表达式

    Lambda表达式 jdk 1.8 新加入的特性,简化了简单接口的实现 函数式接口 函数式中只有一个待实现的方法,可以使用@FunctionalInterface注解标注函数式接口.这个接口中只能有一 ...

最新文章

  1. linux下软链接与硬链接
  2. vs shortcut
  3. 猿辅导、作业帮忙“圈钱”,跟谁学、有道、51Talk狂“烧钱”,在线教育钱途在哪?
  4. 成为C++高手之实战项目
  5. python版本安装
  6. 【通信仿真】基于matlab多域网络仿真【含Matlab源码 1794期】
  7. 文件打印服务器解决方案
  8. window-批量创建文件夹
  9. SQL查询本周过生日的同学,和下周过过生日的同学
  10. oracle 用户权限设置,oracle用户权限管理使用详解
  11. 深恶痛绝!关闭win10自动更新的办法
  12. 产品新人如何才能找到第一份产品工作?
  13. 中学-知识与能力【10】
  14. synchronized(this)和synchronized(.class)的理解
  15. 单片机 TM4C123GXL 学习 例程
  16. undefined local variable or method `daemonize‘ for puma
  17. 设计模式讲解与代码实践(二十三)——模板方法
  18. 弘辽科技:淘宝直通车智能推广报告如何解?
  19. 十二星座的12种风味咖啡,最后一个能让你上瘾
  20. TI Lab_SRR学习_1 硬件基础 AWR1642和AWR1642EVM

热门文章

  1. 26个你需要学习的Firefox配置技巧,改进体验和加快浏览器响应速度
  2. 夺命雷公狗---无限极分类NO1
  3. ASP.NET Aries 入门开发教程6:列表数据表格的格式化处理及行内编辑
  4. Matlab 列主元高斯消去法
  5. ZJ-5型积层压电测试仪(积层静压电系数d33测量仪)
  6. vscode主题安装
  7. EF | Entity framework
  8. Win32下的打印作业输出
  9. hihoCoder 1362 修补木桶
  10. npm报错:A complete log of this run can be fund in: C\Users\administrator\AppData\Roaming\npm-cache_log