Lambda表达式

为什么使用lambda表达式

Lambda表达式可以简化我们的代码,使我们只需要关注主要的代码就可以。

  1. //测试用的实体类
  2. public class Employee {
  3. private String name;
  4. private Integer age;
  5. private double salary;
  6. public Employee() {
  7. }
  8. public Employee(String name, Integer age, double salary) {
  9. this.name = name;
  10. this.age = age;
  11. this.salary = salary;
  12. }
  13. }
  1. //定义要操作的集合数据
  2. List<Employee> employees = Arrays.asList(
  3. new Employee("张三",18,3000),
  4. new Employee("李四",18,3000),
  5. new Employee("张三",45,8700),
  6. new Employee("王五",26,4500),
  7. new Employee("麻子",30,2700),
  8. new Employee("田七",15,200)
  9. );
  1. //需求找出年龄大于20的员工
  2. ---------------最常规的操作--------
  3. //过滤方法
  4. public List<Employee> filterEmployee(List<Employee> employees){
  5. ArrayList<Employee> list = new ArrayList<>();
  6. for (Employee employee : employees) {
  7. if(employee.getAge() > 20){
  8. list.add(employee);
  9. }
  10. }
  11. return list;
  12. }
  13. //测试方法
  14. @Test
  15. public void test1(){
  16. List<Employee> employees = filterEmployee(this.employees);
  17. for (Employee employee : employees) {
  18. System.out.println(employee);
  19. }
  20. }
  21. //Employee{name='张三', age=45, salary=8700.0}
  22. //Employee{name='王五', age=26, salary=4500.0}
  23. //Employee{name='麻子', age=30, salary=2700.0}
  24. -------------第二种写法----------(策略模式)
  25. 1、先定义一个接口
  26. public interface MyPredicate<T> {
  27. public boolean test(T t);
  28. }
  29. 2、定义过滤类实现我们定义的接口
  30. public class FilterEmployeeByAge implements MyPredicate<Employee>{
  31. @Override
  32. public boolean test(Employee employee) {
  33. return employee.getAge()>20;
  34. }
  35. }
  36. 3、同样定义过滤方法
  37. //过滤方法
  38. public List<Employee> filterEmployee(List<Employee> employees, Mypredicatre<Employee> mp){
  39. ArrayList<Employee> list = new ArrayList<>();
  40. for (Employee employee : employees) {
  41. if(mp.test){
  42. list.add(employee);
  43. }
  44. }
  45. return list;
  46. }
  47. 4、测试方法
  48. @Test
  49. public void test2(){
  50. List<Employee> employees = filterEmployee(this.employees, new FilterEmployeeByAge());
  51. for (Employee employee : employees) {
  52. System.out.println(employee);
  53. }
  54. }
  55. //Employee{name='张三', age=45, salary=8700.0}
  56. //Employee{name='王五', age=26, salary=4500.0}
  57. //Employee{name='麻子', age=30, salary=2700.0}
  58. -----------上面的方法每过滤不同的条件都要实现一个接口,不是很友好---------我们可以使用匿名内部类
  59. @Test
  60. public void test3(){
  61. List<Employee> employees = filterEmployee(this.employees, new MyPredicate<Employee>() {
  62. @Override
  63. public boolean test(Employee employee) {
  64. return employee.getAge() > 20;
  65. }
  66. });
  67. -----------------匿名内部类可以使用lambda表达式简化----------
  68. @Test
  69. public void test4(){
  70. List<Employee> employees = filterEmployee(this.employees, (e) -> e.getAge() > 20);
  71. for (Employee employee : employees) {
  72. System.out.println(employee);
  73. }
  74. }

lambda表达式需要函数式接口支持。

函数式接口:只有一个方法的接口,可以用注解@FunctionalInterface修饰接口

语法格式:

  • 无参数,无返回值 ()->System.out.println("hello word")
  1. @Test
  2. public void test(){
  3. Runnable r = new Runnable() {
  4. @Override
  5. public void run() {
  6. System.out.println("hello world");
  7. }
  8. };
  9. //------------------lambda-----------------------------
  10. Runnable r1 = ()-> System.out.println("hello world");
  11. }
  • 有一个参数,无返回值 (x)-> System.out.println(x) (有一个参数小括号可以不写)
  1. @Test
  2. public void test2(){
  3. Consumer<String> con = (x)-> System.out.println(x);
  4. //Consumer<String> con = x-> System.out.println(x);
  5. con.accept("hello world");
  6. }
  • 有两个参数,且有返回值 (有多条语句,必须使用{})
  1. @Test
  2. public void test3(){
  3. Comparator<Integer> com = (x,y)->{
  4. System.out.println("函数式接口");
  5. return Integer.compare(x,y);
  6. };
  7. }
  • 有两个参数,且有返回值,语句只有一条 (return 和{} 可以省略)
  1. @Test
  2. public void test4(){
  3. Comparator<Integer> com = (x,y)->Integer.compare(x,y);
  4. }
  • lambda参数列表的数据类型可以省略不用写(类型推断)(要写都得写,不能写一个,一个不写)

java8中4大核心接口

Consumer : 消费型接口

​ void accept(T t);

  1. @Test
  2. public void test4(){
  3. happy(1000,(m) -> System.out.println("你消费了:"+m+"元"));
  4. }
  5. public void happy(double money, Consumer<Double> con){
  6. con.accept(money);
  7. }

Supplier : 供给型接口

​ T get();

  1. @Test
  2. //获取随机数
  3. public void test5() {
  4. List<Integer> numList = getNumList(5, () -> (int) (Math.random() * 10));
  5. System.out.println(numList.toString());
  6. }
  7. //产生整数集合
  8. public List<Integer> getNumList(int num, Supplier<Integer> sup) {
  9. ArrayList<Integer> list = new ArrayList<>();
  10. for (int i = 0; i < num; i++) {
  11. list.add(sup.get());
  12. }
  13. return list;
  14. }

Function<T,R>: 函数式接口

​ R apply(T t);

  1. @Test
  2. public void test6(){
  3. String str = strHandle("hello world", (s) -> s.substring(2, 5));
  4. System.out.println(str);
  5. }
  6. //对字符串进行处理返回一个字符串
  7. public String strHandle(String str, Function<String,String> fun){
  8. return fun.apply(str);
  9. }

Predicate: 断言型接口

​ boolean test(T t);

  1. @Test
  2. public void test7(){
  3. List<String> strings = Arrays.asList("hello", "world", "qw", "das", "s", "sadui");
  4. List<String> str = filterStr(strings, (s) -> s.length() > 3);
  5. System.out.println(str.toString());
  6. }
  7. //对字符串数组进行过滤
  8. public List<String> filterStr(List<String> str, Predicate<String> pre){
  9. ArrayList<String> list = new ArrayList<>();
  10. for (String s : str) {
  11. if(pre.test(s)){
  12. list.add(s);
  13. }
  14. }
  15. return list;
  16. }

方法引用: 如果lambda体中的内容方法已经实现我们可以使用方法引用。

​ lambda表达式的另一种表现形式,

主要有三种语法格式:

Lambda体中方法的返回值要与实例方法返回值类型一致

  • 对象::实例方法名

  1. @Test
  2. public void test8(){
  3. Consumer<String> con = (s) -> System.out.println(s);
  4. Consumer<String> con1 = System.out::println;
  5. PrintStream ps = System.out;
  6. Consumer<String> con2 = ps::println;
  7. Employee emp = new Employee();
  8. Supplier<Integer> sup = () -> emp.getAge();
  9. Integer age = sup.get();
  10. Supplier<Integer> sup1 = emp::getAge();
  11. Integer age1 = sup1.get();
  12. }
  • 类::静态方法名
  1. @Test
  2. public void test9(){
  3. Comparator<Integer> com = (x,y)-> Integer.compare(x,y);
  4. Comparator<Integer> com1 = Integer::compare;
  5. }
  • 类::实例方法名

    第一个参数是实例方法的调用者,第二参数是实例方法的参数才可以使用

  1. @Test
  2. public void test10(){
  3. BiPredicate<String,String> pre = (x,y)-> x.equals(y);
  4. BiPredicate<String,String> pre1 = String::equals;
  5. }

构造器引用:

className::new

​ 需要调用的构造器函数列表要与函数式接口中的抽象方法的参数列表保持一致

  1. @Test
  2. public void test1(){
  3. Supplier<Employee> sup = () -> new Employee();
  4. //调用的是无参构造器
  5. Supplier<Employee> sup1 = Employee::new;
  6. //调用的是带有一个参数的构造器
  7. Function<Integer,Employee> fun = Employee::new;
  8. }

数组引用:

Type[]::new

  1. @Test
  2. public void test1(){
  3. Function<Integer,String[]> fun = (x)-> new String[x];
  4. Function<Integer,String[]> fun1 = String[]::new;
  5. }

lambda表达式的学习的更多相关文章

  1. C++11 里lambda表达式的学习

    最近看到很多关于C++11的文档,有些是我不怎么用到,所以就略过去了,但是lambda表达式还是比较常用的,其实最开始学习python的时候就觉得lambda这个比较高级,为什么C++这么弱.果然C+ ...

  2. 【Java】Java8新增的Lambda表达式_学习笔记

    一.Lambda表达式可以简化创建匿名内部类对象 1.不需要new XXX(){}这种繁琐代码. 2.不需要指出重写的方法名. 3.不要给出重写的方法的返回值类型. 4.Lambda相当于一个匿名方法 ...

  3. Spring8中lambda表达式的学习(Function接口、BiFunction接口、Consumer接口)

    代码重构,为了确保功能的等效性,梳理代码时,发现如下代码: public SingleRespTTO fundI(SingleReqTTO request) throws Exception { re ...

  4. C#中匿名委托以及Lambda表达式的学习笔记

    一. C#从1.0到4.0, 随着Linq,泛型的支持,代码越来越简单优雅 , , , , , , , , , }; IEnumerable< select n; newNums = newNu ...

  5. 【Java学习笔记之三十一】详解Java8 lambda表达式

    Java 8 发布日期是2014年3月18日,这次开创性的发布在Java社区引发了不少讨论,并让大家感到激动.特性之一便是随同发布的lambda表达式,它将允许我们将行为传到函数里.在Java 8之前 ...

  6. Java基础学习总结(44)——10个Java 8 Lambda表达式经典示例

    Java 8 刚于几周前发布,日期是2014年3月18日,这次开创性的发布在Java社区引发了不少讨论,并让大家感到激动.特性之一便是随同发布的lambda表达式,它将允许我们将行为传到函数里.在Ja ...

  7. 深入浅出 Java 8 Lambda 表达式

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

  8. Java 8 Lambda表达式10个示例【存】

    PS:不能完全参考文章的代码,请参考这个文件http://files.cnblogs.com/files/AIThink/Test01.zip 在Java 8之前,如果想将行为传入函数,仅有的选择就是 ...

  9. jdk8 lambda表达式总结

    Java8 lambda表达式10个示例   1. 实现Runnable线程案例 使用() -> {} 替代匿名类: //Before Java 8: new Thread(new Runnab ...

随机推荐

  1. 【九度OJ】题目1192:回文字符串 解题报告

    [九度OJ]题目1192:回文字符串 解题报告 标签(空格分隔): 九度OJ http://ac.jobdu.com/problem.php?pid=1192 题目描述: 给出一个长度不超过1000的 ...

  2. 【LeetCode】680. Valid Palindrome II 验证回文字符串 Ⅱ(Python)

    作者: 负雪明烛 id: fuxuemingzhu 个人博客: http://fuxuemingzhu.cn/ 目录 题目描述 题目大意 解题方法 双指针 思路来源 初版方案 进阶方案 日期 题目地址 ...

  3. 【LeetCode】877. Stone Game 解题报告(Python & C++)

    作者: 负雪明烛 id: fuxuemingzhu 个人博客: http://fuxuemingzhu.cn/ 目录 题目描述 题目大意 解题方法 数学 双函数 单函数 + 记忆化递归 动态规划 日期 ...

  4. P1753HackSon的趣味题

    1 #include<stdio.h> 2 #include<algorithm> 3 #include<iostream> 4 #include<stdli ...

  5. idea使用教程-模板的使用

    一.代码模板是什么 它的原理就是配置一些常用代码字母缩写,在输入简写时可以出现你预定义的固定模式的代码,使得开发效率大大提高,同时也可以增加个性化.最简单的例子就是在Java中输入sout会出现Sys ...

  6. python语法糖之有参装饰器、无参装饰器

    python的装饰器简单来说就是函数的一种形式,是为了扩展原来的函数功能而设计的. 装饰器的特别之处在于它的返回值也是一个函数,可以在不改变原有函数代码的基础上添加新的功能 # 先定义一个函数及引用# ...

  7. Linux磁盘分区与挂载

    原理介绍 在Linux世界中,一切皆目录,每一块硬盘分区对应Linux的一个目录,所以我们可以通过管理目录来管理硬盘分区,而将硬盘分区与文件目录关联的操作就成为"挂载"[mount ...

  8. Java基础寒假作业-简易计算器

    需求: 使用Java编写计算器的控制台程序,完成简单的加减乘除运算.实现以下功能: 1.运算选择 请用户选择一个算法(1.加法 2.减法 3.乘法 4.除法 5.关闭计算器) 2.计算 a)加法:实现 ...

  9. Django admin实现TextField字段changelist页面换行、空格正常显示

    问题背景 在Django后台的使用admin view绑定model后,可以很方便的通过网页对底层的数据表进行增删查改操作. 在实际工作中有一些数据字段会存储了json或者其他包含换行符.空格符的文本 ...

  10. (五)React Ant Design Pro + .Net5 WebApi:后端环境搭建-Autofac注入+ 泛型仓储

    一. 简介 Autofac与.Net Core自带DI的区别,大佬级的文章数不胜数.我只是根据实际应用简单介绍(非常简单的那种) 1.批量注入,自带DI需要自己写循环反射注入,Autofac现成方法, ...