java新特性lambda表达式快速入门
文章目录
- 序
- 常规写法
- 写法一:新建类并实现该接口
- 写法二:使用匿名函数
- 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简写
仔细观察可以发现写法一中仍然有多余的代码,比如说我们在之前的接口中已经声明过一次入参的类型,在使用的时候又声明了一次,这显然是多余的写法。其实上面的写法依然可以更简洁,只要满足下面这几点,都可以省略。
- 当入参类型和初始定义类型一致时,可以省略入参类型。
- 当方法体中只有一句代码时,可以省略大括号。
- 当方法体中只有一句代码,并且需要返回值时,可以省略
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)
,这么写就已经是非常的简洁了,但这么写需要满足两个基本条件:
- 只有接口中抽象方法的参数格式跟定义的方法参数格式一样,才能省略参数。
- 接口中抽象方法的返回值必须跟定义的方法的返回值一样。
这就是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的方式??
答案
- 排序(二选一)
list.sort((p1,p2) -> p1.getAge() - p2.getAge());
Collections.sort(list,(p1,p2) -> p1.getAge() - p2.getAge());
- 遍历
list.forEach(person -> System.out.println(person.toString()));
- 删除指定元素
list.removeIf(person -> person.age > 35);
java新特性lambda表达式快速入门相关推荐
- Java 8 新特性 lambda表达式
/ Created by Manager on 2021/4/1. Java 8 新特性 lambda表达式 StreamAPI 新日期 新注解 */ 视频连接 1https://www.bilibi ...
- java lambda表达式详解_Java8新特性Lambda表达式详解
课程目标: 通过本课程的学习,详细掌握Java8新特性之Lambda表达式: 适用人群:有Java基础的开发人员: 课程概述:从Java 8出现以来lambda是最重要的特性之一,它可以让我们用简洁流 ...
- Java 8 新特性Lambda 表达式
Java 8 新特性Lambda 表达式 一.常用循环 二.匿名内部类 三.排序集合 四.循环打印对象 五.根据条件修改 六.排序 七.求和 八.统计方法 九.材料 一.常用循环 public cla ...
- Java8新特性----Lambda表达式详细探讨
Java8新特性 Lambda表达式 入门演示 案例1 如何解决 cannot be cast to java.lang.Comparable问题? 案例2 优化方式一 : 策略设计模式 优化方式二: ...
- C++11新特性——λ(lambda)表达式详解
C++11新特性--λ(lambda)表达式 C++11中引入了λ表达式,它可以用来定义一个内联(inline)的函数,作为一个本地的对象或者一个参数.有了λ表达式,我们可以很方便的使用stl标准库. ...
- JDK1.8新特性Lambda表达式入门
摘要:此篇文章主要介绍 Java8 Lambda 表达式产生的背景和用法,以及 Lambda 表达式与匿名类的不同等.本文系 OneAPM 工程师编译整理. Java 是一流的面向对象语言,除了部分简 ...
- java8新特性lambda表达式、函数式编程、方法引用和接口默认方法以及内部类访问外部变量
一提到java是一种什么语言? 大多数人肯定异口同声的说是一门面向对象的语言,这种观点从我们开始学java就已经根深蒂固了,但是学到java8新特性函数式编程的时候,我才知道java并不是纯面向对象的 ...
- java8新特性-lambda表达式入门学习
定义 jdk8发布新特性中,lambda是一大亮点之一.lambda表达式能够简化我们对数据的操作,减少代码量,大大提升我们的开发效率.Lambda 表达式"(lambda expressi ...
- 【Java】jdk 1.8 新特性——Lambda表达式
Lambda表达式 jdk 1.8 新加入的特性,简化了简单接口的实现 函数式接口 函数式中只有一个待实现的方法,可以使用@FunctionalInterface注解标注函数式接口.这个接口中只能有一 ...
最新文章
- linux下软链接与硬链接
- vs shortcut
- 猿辅导、作业帮忙“圈钱”,跟谁学、有道、51Talk狂“烧钱”,在线教育钱途在哪?
- 成为C++高手之实战项目
- python版本安装
- 【通信仿真】基于matlab多域网络仿真【含Matlab源码 1794期】
- 文件打印服务器解决方案
- window-批量创建文件夹
- SQL查询本周过生日的同学,和下周过过生日的同学
- oracle 用户权限设置,oracle用户权限管理使用详解
- 深恶痛绝!关闭win10自动更新的办法
- 产品新人如何才能找到第一份产品工作?
- 中学-知识与能力【10】
- synchronized(this)和synchronized(.class)的理解
- 单片机 TM4C123GXL 学习 例程
- undefined local variable or method `daemonize‘ for puma
- 设计模式讲解与代码实践(二十三)——模板方法
- 弘辽科技:淘宝直通车智能推广报告如何解?
- 十二星座的12种风味咖啡,最后一个能让你上瘾
- TI Lab_SRR学习_1 硬件基础 AWR1642和AWR1642EVM
热门文章
- 26个你需要学习的Firefox配置技巧,改进体验和加快浏览器响应速度
- 夺命雷公狗---无限极分类NO1
- ASP.NET Aries 入门开发教程6:列表数据表格的格式化处理及行内编辑
- Matlab 列主元高斯消去法
- ZJ-5型积层压电测试仪(积层静压电系数d33测量仪)
- vscode主题安装
- EF | Entity framework
- Win32下的打印作业输出
- hihoCoder 1362 修补木桶
- npm报错:A complete log of this run can be fund in: C\Users\administrator\AppData\Roaming\npm-cache_log