Java8新特性-Lambda表达式

这篇具有很好参考价值的文章主要介绍了Java8新特性-Lambda表达式。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

java8 新特性

Lambda表达式

Lambda是一个匿名函数, 可以把lambda表达式理解为是一段可以传递的代码,(将代码像数据一样传递)

 // 比较两个整数的大小------采用匿名内部类的方式
 @Test
     public void test1(){
         Comparator<Integer> comp = new Comparator<Integer>() {
             @Override
             public int compare(Integer o1, Integer o2) {
                 return o1.compareTo(o2);
             }
         };
         System.out.println(comp.compare(9, 5));
    
     }
 ​
  
  // 比较两个整数的大小------采用 lambda
         Comparator<Integer> comp2 = (a, b) -> a.compareTo(b);
         System.out.println(comp2.compare(10, 4));
 ​

变化 需求: 求 薪资高于5000的员工信息

 // 建立 员工类 Emp, 包含姓名 薪资,年龄
 import lombok.AllArgsConstructor;
 import lombok.Data;
 import lombok.NoArgsConstructor;
 import lombok.ToString;
 ​
 @NoArgsConstructor
 @AllArgsConstructor
 @Data
 @ToString
 public class Emp {
     private String name;
     private double salary;
     private int age;
 }
 ​
 //编写 测试类
 // 查询 薪资高于5000的员工信息
  private List<Emp> filterEmp(List<Emp> emps){
         List<Emp> list2 = new ArrayList<>();
         for (Emp emp: emps) {
             if(emp.getSalary()>5000){
                 list2.add(emp);
             }
         }
         return list2;
     }
 ​
 //查询 年龄大于30的员工信息
  private List<Emp> filterEmp(List<Emp> emps){
         List<Emp> list2 = new ArrayList<>();
         for (Emp emp: emps) {
             if(emp.getAge()>30){
                 list2.add(emp);
             }
         }
         return list2;
     }
 // 查询 年龄小于20 或 查询 薪资低于7000的, 发现 每变更一次需求, 总是要 编写一个新的方法, 而且 大部分代码相同
 // 只有关键条件的代码不同, 因此 造成了 数据的 大量冗余,  那 如何改进呢?
 ​
 // 利用所学--- 采用设计模式改进, 定义接口, 接口里定义抽象方法 返回boolean,采用不同的实现类来操作, 每个需求都是不同的实现类,
 /**
     定义接口 MyEmp<T>  定义 方法 boolean test(T t);
 */
 // 定义接口
 public interface MyEmp<T>{
     boolean test(T t);
 }
 ​
 ​
 //定义实现类-- 按照薪资过滤
 public class FilterBySalary implements MyEmp<Emp>{
     @Override
     public boolean test(Emp emp) {
         return emp.getSalary()>5000;
     }
 }
 ​
 //定义实现类--按照年龄过滤
 public class FilterEmpByAge implements MyEmp<Emp>{
     @Override
     public boolean test(Emp emp) {
         return emp.getAge()>30;
     }
 }
 ​
 //测试类中 , 编写方法, 以接口作为参数
  private List<Emp> filterEmp(List<Emp> emps, MyEmp<Emp> filter){
         List<Emp> list2 = new ArrayList<>();
         for (Emp emp: emps) {
             if(filter.test(emp)){
                 list2.add(emp);
             }
         }
         return list2;
     }
 // 测试方法 
     @Test
     public void test1() {
 ​
         //按照年龄过滤
         List<Emp> emps = filterEmp(list,new FilterEmpByAge());
         System.out.println(emps);
         //按照薪资过滤
         List<Emp> emps2 = filterEmp(list,new FilterBySalary());
         System.out.println(emps2);
     }
 ​
 // 以上问题 可以得到解决, 但目前是采用了 设计模块(策略模式) 进行 代码优化,缺点: 就是每次都要编写实现类,怎么再次优化?
 ​
 //  优化上述问题,采用匿名内部类的方式,  只需要定义接口, 不需要 实现类
 ​
 @Test
     public void test1() {
 ​
 ​
         List<Emp> emps = filterEmp(list, new MyEmp<Emp>() {
             @Override
             public boolean test(Emp emp) {
                 return emp.getSalary()>50000;
             }
         });
         System.out.println(emps);
 ​
         List<Emp> emps2 = filterEmp(list, new MyEmp<Emp>() {
             @Override
             public boolean test(Emp emp) {
                 return emp.getAge()>30;
             }
         });
         System.out.println(emps2);
     }
 // 以上代码 关键的就是比较那一句, 显得代码不简洁, 因此能不能再次优化?   可以使用  Lambda表达式
  @Test
     public void test1() {
 ​
         List<Emp> emps = filterEmp(list, emp->emp.getSalary()>5000);
         emps.forEach(System.out::println);
 ​
         List<Emp> emps2 = filterEmp(list, emp->emp.getAge()>40);
         emps2.forEach(System.out::println);
     }
 ​
 // 以上代码 还有使用 stream 再次优化
 list.stream().filter(e->e.getSalary()>5000).forEach(System.out::println);
 list.stream().filter(e->e.getAge()>40).forEach(System.out::println);

Lambda基本语法

在 java8 中引入了一个新的操作符 "->" , 箭头操作符, 箭头操作符 将Lambda表达式拆分为两部分:

左侧: Lambda表达式的参数列表

右侧: Lambda表达式的所需执行的功能, 即Lambda体

语法格式一: 无参数 无返回值-------- 举例 Runnable 接口中的void run() 方法

示例: (注意: 不能在lambda内部 修改定义在域外的局部变量, 否则会 编译错误)

 Runnable r = ()->System.out.println("hello lambda");
 r.run();

语法格式二: 有一个参数, 无返回值 -- Consumer接口中 void accept(T t) 方法

示例:

 Consumer<String> str = x->System.out.println(x); // 箭头左侧 x的小括号省略
 str.accept("nihao");// nihao赋值给x, 并进行打印

语法格式三: 若 只有一个参数,则参数的小括号 可不写

语法格式四: 有两个以上的参数 有返回值,并且 Lambda体中 有多条语句 , 则 {} 不可以省略--- Comparator接口 int compare(int x,int y)

举例:

 Comparator<Integer> comp = (x,y)->{
  System.out.println("语句1");
  return Integer.compare(x,y);
 };
 System.out.println(comp.compare(5, 7));

语法格式五:有两个以上的参数 有返回值,并且 Lambda体中 有一条语句 , 则 {} 和return 均可以省略

示例: Comparator<Integer> comp = (x,y)-> Integer.compare(x,y);

语法格式六: Lambda表达式的参数列表的数据类型可以省略不写, 因为 JVM编译器会通过上下文推断出参数的数据类型-- 即 类型推断

List<String> list = new ArrayList<>(); // 等号右侧 的 <> 里面不需要写类型了, 这也是 类型推断 , 1.7会报错

总结: 左右遇一 括号省, 左侧推断类型省,

函数式接口

Lambda表达式 需要函数式接口的 支持,

什么是函数式接口?

接口中只有一个抽象方法的接口 称为 函数式接口 ,可以使用 @FunctionalInterface 修饰, 检查是否是 函数式 接口

Lambda表达式练习题

1.调用Collections.sort()方法,通过定制排序比较两个Emp(先按年龄比,年龄相同 按姓名比),使用 Lambda 作为参数传递。 Emp.java 中 包含 姓名, 年龄 字段

 @Test
     public void test(){
         List<Emp> list = Arrays.asList(
                 new Emp("王丽",3000,50),
                 new Emp("李四",5000,50),
                 new Emp("王丽2",3000,60),
                 new Emp("李四2",3000,50)
         );
         Collections.sort(list,(e1,e2)->{
             if(e1.getAge()==e2.getAge()){
                 return e1.getName().compareTo(e2.getName());
             }else{
                 return Integer.compare(e1.getAge(),e2.getAge());
             }
         });
 ​
         list.forEach(System.out::println);
     }
 ​

2.①声明函数式接口,接口中声明抽象方法,public String getValue(String str); ②声明类 TestLambda ,类中编写方法使用接口作为参数,将一个字符串转换成大写,并作为方法的返回值。 ③再将一个字符串的第2个和第4个索引位置进行截取子串。

 // 定义函数式 接口
 @FunctionalInterface
 public interface MyTestLambda {
      String getValue(String str);
 }
 ​
 // 定义测试类- 并添加 方法
 // 对s 执行 lambda的操作
  public String change(String s, MyTestLambda lambda){
         return lambda.getValue(s); //调用接口方法
     }
 ​
 // 测试类-- 测试方法
     @Test
     public void test2(){
         //转大写
         String s = change("abc123",x->x.toUpperCase());
         System.out.println(s);
         // 提取 索引2-4 之间的内容
         String s1 = change("abc123",x->x.substring(2,5));
         System.out.println(s1);
 ​
     }

3.①声明一个带两个泛型的函数式接口,泛型类型为<T, R> T为参数,R为返回值 ②接口中声明对应抽象方法。 ③在 TestLambda类中声明方法,使用接口作为参数,计算两个long型参数的和。④再计算两个long型参数的乘积。

 // 定义接口
 @FunctionalInterface
 public interface MyFun<T,R> {
     R change(T t1,T t2);  // 因为要求对两个数 进行计算
 }
 ​
 // 定义 测试类-- 添加方法 , 对 t1, t2 两数 做 lambda的操作
  public Long change3(Long t1,Long t2,MyFun<Long,Long> lambda){
         return lambda.change(t1,t2);
    }
 //定义测试类- 测试方法
  @Test
     public void test3(){
         //计算两数 和
        Long sum = change3(5l,10l,(x,y)->x+y);
         System.out.println(sum);
         //计算两数 积
         Long sum2 = change3(5l,10l,(x,y)->x*y);
         System.out.println(sum2);
     }
 ​

本次练习发现 每次都需要自定义接口,实际上新特性已经提供了函数式接口,下节课学习下文章来源地址https://www.toymoban.com/news/detail-790577.html

到了这里,关于Java8新特性-Lambda表达式的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Java新特性:Lambda表达式

    Java新特性:Lambda表达式 Lambda 表达式(Lambda expression),也可称为闭包(Closure),是 Java(SE)8 中一个重要的新特性。Lambda 表达式允许我们通过表达式来代替功能接口。Lambda 表达式就和方法一样,它提供了一个正常的参数列表和一个使用这些参数的主体(body,可以是一个表

    2024年02月13日
    浏览(56)
  • Java 8 新特性之Lambda表达式

    函数式编程(Functional Programming)是把函数作为基本运算单元,函数可以作为变量,可以接收函数,还可以返回函数。历史上研究函数式编程的理论是Lambda演算,所以我们经常把支持函数式编程的编码风格称为Lambda表达式。 在Java中使用Lambda表达式的前提:需要是函数接口。

    2024年01月22日
    浏览(46)
  • Java 8 新特性——Lambda 表达式(2)

            Java Stream函数式编程接口最初在Java 8中引入,并且与 lambda 一起成为Java开发里程碑式的功能特性,它极大的方便了开放人员处理集合类数据的效率。         Java Stream就是一个数据流经的管道,并且在管道中对数据进行操作,然后流入下一个管道。有学过linux

    2024年02月11日
    浏览(42)
  • JAVA8-lambda表达式8:在设计模式-模板方法中的应用

    JAVA8-lambda表达式1:什么是lambda表达式 JAVA8-lambda表达式2:常用的集合类api JAVA8-lambda表达式3:并行流,提升效率的利器? JAVA8-lambda表达式4:Optional用法 java8-lambda表达式5:toMap引发的线上故障 JAVA8-lambda表达式6:重构和定制收集器 JAVA8-lambda表达式7:重要的函数接口 最近在公司

    2024年02月14日
    浏览(52)
  • 【Java系列】JDK 1.8 新特性之 Lambda表达式

    Lambda是一个匿名函数,我们可以将Lambda表达式理解为一段可以传递的代码(将代码像数据一样传递)。使用它可以写出简洁、灵活的代码。作为一种更紧凑的代码风格,使java语言表达能力得到提升。 结果: ​19:43:39.303 [main] INFO com.chen.test.JAVA8Features.Demo01 - 我是没有使用Lambda表

    2024年02月22日
    浏览(49)
  • Java—JDK8新特性—Lambda表达式【内含思维导图】

    目录 JDK8新特性 2.Lambda表达式 思维导图 2.1 什么是Lambda表达式 2.2 为什么使用Lamdba表达式 2.3 Lambda表达式基本语法 2.4 类型推断 2.5 Lambda练习 2.6 Lambda常用场景         官网提供网址:JDK 8 Features         Lamdba是一个 匿名函数 ,可以把Lamdba表达式理解为是一段可以传递的

    2024年02月03日
    浏览(48)
  • Java 8及以上新特性:Lambda表达式、Stream API、Optional类与接口默认方法(四)

    目录 一、接口默认方法 1.1 概念解析: 1.2 应用场景: 1.3 使用注意事项: 1.4 使用示例: 二、结论 1.1 总结Java 8及以上版本四大新特性的重要意义与价值: 1.2 鼓励读者积极学习并运用这些新特性: 1.3 对未来Java版本可能引入的新特性进行展望: 1.1 概念解析: 接口默认方法

    2024年04月13日
    浏览(43)
  • java学习路程之篇三、进阶知识、面向对象高级、接口新特性、代码块、内部类、Lambda表达式、窗体、组件、事件

    概述 生成值类型响应式数据 通过 .value 值修改 生成对象和数组类型的响应式对象选用 reactive 方式比较好 html JavaScript 概述 reactive 方法根据传入的对象,创建返回一个深度响应式对象。响应式对象看起来和传入的对象一样。但是,响应式对象属性值改动,不管层级有多深,都

    2024年02月16日
    浏览(38)
  • 进阶JAVA篇- Lambda 表达式与 Lambda 表达式的省略规则

    目录         1.0 什么是 Lambda 表达式?         1.1 既然跟匿名内部类相关,先来回顾匿名内部类。          1.2 Lambda 表达式与匿名内部类之间的关系。         1.3 函数式接口         1.4 在具体代码中来操作一下         2.0 Lambda 表达式省略规则          Lambda 表达

    2024年02月08日
    浏览(55)
  • Lambda表达式(JAVA)

    注:如果没有学过 匿名内部类 和 接口 不推荐往下看。 (parameters) - expression 或 (parameters) -{ statements; } parameters:表示参数列表; -:可理解为“被用于”的意思; expression:表示一条语句; statements:表示多条语句。 Lambda可以理解为:Lambda就是匿名内部类的简化。 lambda表达式

    2024年02月08日
    浏览(54)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包