Java8新特性2:Lambda表达式

回顾之前《JavaSE-23.3》:
https://www.cnblogs.com/yppah/p/14875254.html
https://www.cnblogs.com/yppah/p/14875479.html
https://www.cnblogs.com/yppah/p/14875492.html
https://www.cnblogs.com/yppah/p/14875500.html
https://www.cnblogs.com/yppah/p/14875507.html

  1. 什么是lambda表达式

Lambda 表达式(lambda expression)是一个匿名函数,简化我们调用匿名函数的过程。

Lambda好处: 简化我们匿名内部类的调用。

Lambda+方法引入 代码变得更加精简。

package com.yppah.service;

/**
 * @Author: haifei
 * @Date: 2022/7/20 19:35
 */
public interface OrderService {

    void get();
    /**
     * 如果需要使用到OrderService接口
     * 接口是无法new、可以通过匿名内部类new
     */

}

package com.yppah.myLambda;

import com.yppah.service.OrderService;

/**
 * @Author: haifei
 * @Date: 2022/7/20 19:44
 */
public class Test02 {

    public static void main(String[] args) {
        /*// 通过匿名内部类创建一个接口的子类,用父类(接口)接收
        // 通过匿名内部类的方式调用接口中的方法
        OrderService orderService = new OrderService() {
            @Override
            public void get() { //匿名内部类
                System.out.println("get");
            }
        };
        orderService.get();*/

        // 简写
        /*new OrderService() {
            @Override
            public void get() { //匿名内部类
                System.out.println("get");
            }
        }.get();*/
        ((OrderService) () -> {
            System.out.println("get");
        }).get();

        /*new Thread(new Runnable() {
            @Override
            public void run() {
                System.out.println(Thread.currentThread().getName()+" :run...");
            }
        }).start();*/
        new Thread(() ->
                System.out.println(Thread.currentThread().getName()+" :run...")
        ).start();

    }
}

Java8新特性2:Lambda表达式
  1. lambda表达式规范

2.1 函数接口定义

Java中使用Lambda表达式的规范,必须是为函数接口

函数接口的定义:在该接口中只能存在一个抽象方法,该接口称作为函数接口

使用Lambda表达式 依赖于函数接口

  • 在函数接口中只能够允许有一个抽象方法
  • 在函数接口中可以定义object类中方法
  • 可以使用默认或者静态方法
  • @FunctionalInterface 表示该接口为函数接口
package com.yppah.myLambda.p2;

/**
 * @Author: haifei
 * @Date: 2022/7/20 20:29
 */
@FunctionalInterface // 函数接口(要求该接口中只能有一个抽象函数,不然注解会报错。但可以有默认或静态方法)
public interface MyFunctionalInterface {
    void get();

    default void add(){
        System.out.println("add");
    }

    // 在函数接口中定义object类中方法
    String toString();
}

2.2 java内置的函数接口

JDK中自带的函数接口:

  • java.lang.Runnable
  • java.util.concurrent.Callable
  • java.security.PrivilegedAction
  • java.util.Comparator
  • java.io.FileFilter
  • java.nio.file.PathMatcher
  • java.lang.reflect.InvocationHandler
  • java.beans.PropertyChangeListener
  • java.awt.event.ActionListener
  • javax.swing.event.ChangeListener

java系统内置哪些函数接口?

Java8新特性2:Lambda表达式

Java8新特性2:Lambda表达式

2.2.1 消费型接口

Conusmer
       void accept(T t);
BiConusmer
       void accept(T t,U u);//增加一种入参类型

2.2.2 供给型接口

Supplier
       void get();

2.2.3 函数型接口

Function
       R apply(T t);
UnaryOperator
       T apply(T t);//入参与返回值类型一致
BiFunction
       R apply(T t,U u);//增加一个参数类型
BinaryOperator
       T apply(T t1,T t2);//l两个相同类型入参与同类型返回值
ToIntFunction//限定返回int
ToLongFunction//限定返回long
ToDoubleFunction//限定返回double
IntFunction//限定入参int,返回泛型R
LongFunction//限定入参long,返回泛型R
DoubleFunction//限定入参double,返回泛型R

2.2.4 断言型接口

Predicate
       boolean test(T t);

2.3 Lambda语法

参数列表:()
分隔符:->
方法体:{}
()->{}

2.3.1 无参方法调用

Java8新特性2:Lambda表达式
package com.yppah.myLambda.p3;

/**
 * @Author: haifei
 * @Date: 2022/10/25 14:03
 */
@FunctionalInterface
public interface AcanthopanaxInterface {
    void get(); //函数接口必须有且仅有一个抽象方法
}

package com.yppah.myLambda.p3;

import com.yppah.myLambda.p2.MyFunctionalInterface;

/**
 * @Author: haifei
 * @Date: 2022/10/25 14:03
 */
public class Test03 {

    public static void main(String[] args) {
         // 1. 使用匿名内部类调用
        new AcanthopanaxInterface() {
            @Override
            public void get() {
                System.out.println("get");
            }
        }.get();

        // 2. 使用lambda表达式调用
//        ((AcanthopanaxInterface) () -> System.out.println("get")).get();
        AcanthopanaxInterface acanthopanaxInterface = () -> {
            System.out.println("get");
        };
        acanthopanaxInterface.get();
    }
}

2.3.2 带参和返回值

Java8新特性2:Lambda表达式
package com.yppah.myLambda.p4;

/**
 * @Author: haifei
 * @Date: 2022/10/25 14:54
 */
@FunctionalInterface
public interface YouShenInterface {
    String get(int i, int j);
}

package com.yppah.myLambda.p4;

/**
 * @Author: haifei
 * @Date: 2022/10/25 14:54
 */
public class Test04 {
    public static void main(String[] args) {
        // 1. 使用匿名内部类调用
        YouShenInterface youShenInterface = new YouShenInterface() {
            @Override
            public String get(int i, int j) {
                return i + "--" + j;
            }
        };
        System.out.println(youShenInterface.get(1, 2));

        // 2. 使用lambda表达式调用
        YouShenInterface youShenInterface2 = (i, j) -> {
            return i+"--"+j;
        };
        System.out.println(        youShenInterface2.get(3, 4));
    }
}

2.3.3 精简语法

  1. 如果方法体中只有一条语句的情况下,可以不需要写{}
  2. 如果方法体中只有一条return的情况下,不需要些{}和return
package com.yppah.myLambda.p5;

import com.yppah.myLambda.p3.AcanthopanaxInterface;
import com.yppah.myLambda.p4.YouShenInterface;

/**
 * @Author: haifei
 * @Date: 2022/10/25 15:04
 */
public class Test05 {
    public static void main(String[] args) {
        // 1-1
        AcanthopanaxInterface acanthopanaxInterface = () -> {
            System.out.println("无参无返回的lambda");
        };
        acanthopanaxInterface.get();

        // 1-2
        ((AcanthopanaxInterface)()->{
            System.out.println("无参无返回的lambda");
        }).get();

        // 2-1
        AcanthopanaxInterface acanthopanaxInterface2 = () -> System.out.println("无参无返回的lambda");
        acanthopanaxInterface2.get();

        // 2-2
        ((AcanthopanaxInterface)()-> System.out.println("无参无返回的lambda")).get();

        // "有参有返回值的1ambda"
        // 3-1
        YouShenInterface youShenInterface = (i, j) -> {
            return i+"-"+j;
        };
        System.out.println(youShenInterface.get(1, 2));

        // 3-2
        YouShenInterface youShenInterface2 = (i, j) -> i+"-"+j;
        System.out.println(youShenInterface2.get(3, 4));

        // 3-3
        String result = ((YouShenInterface) (i, j) -> i + "-" + j).get(5, 6);
        System.out.println(result);
    }
}

Java8新特性2:Lambda表达式

2.4 lambda案例

2.4.1 foreach集合遍历

Java8新特性2:Lambda表达式
package com.yppah.myLambda.p6;

import java.util.ArrayList;
import java.util.List;
import java.util.function.Consumer;

/**
 * @Author: haifei
 * @Date: 2022/10/25 15:40
 */
public class Test06 {

    public static void main(String[] args) {
        List arrayList = new ArrayList<>();
        arrayList.add("tom");
        arrayList.add("amy");
        arrayList.add("sam");

        /*arrayList.forEach(new Consumer() {
            @Override
            public void accept(String s) {
                System.out.println(s);
            }
        });*/
        arrayList.forEach(s -> System.out.println(s));
    }

}

2.4.2 集合排序

Java8新特性2:Lambda表达式
package com.yppah.myLambda.p6;

/**
 * @Author: haifei
 * @Date: 2022/10/25 15:47
 */
public class User {

    private String userName;
    private int age;

    public User(String userName, int age) {
        this.userName = userName;
        this.age = age;
    }

    public User() {
    }

    public String getUserName() {
        return userName;
    }

    public void setUserName(String userName) {
        this.userName = userName;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    @Override
    public String toString() {
        return "User{" +
                "userName='" + userName + '\'' +
                ", age=" + age +
                '}';
    }
}

package com.yppah.myLambda.p6;

import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;

/**
 * @Author: haifei
 * @Date: 2022/10/25 15:47
 */
public class Test07 {

    public static void main(String[] args) {
        List userList = new ArrayList<>();
        userList.add(new User("tom", 22));
        userList.add(new User("amy", 18));
        userList.add(new User("sam", 26));

        /*userList.sort(new Comparator() {
            @Override
            public int compare(User o1, User o2) {
                return o1.getAge()-o2.getAge();
            }
        });*/
        /*userList.forEach((t) -> {
            System.out.println(t.toString());
        });*/

        /*userList.sort((o1, o2) -> {
            return o1.getAge()-o2.getAge();
        });*/
        userList.sort((o1, o2) -> o1.getAge()-o2.getAge());
        userList.forEach(t -> System.out.println(t.toString()));
    }

}

2.4.3 线程调用

Java8新特性2:Lambda表达式
package com.yppah.myLambda.p6;

/**
 * @Author: haifei
 * @Date: 2022/10/25 16:03
 */
public class Test08 {

    public static void main(String[] args) {
        new Thread(new Runnable() {
            @Override
            public void run() {
                System.out.println("匿名内部类-" + Thread.currentThread().getName());
            }
        }).start();

        new Thread(() -> System.out.println("lambda表达式-" + Thread.currentThread().getName())).start();
    }

}

2.5 方法引入

2.5.1 概念和规则

方法引用提供了非常有用的语法,可以直接引用已有的java类或对象的方法或构造器。方法引用其实也离不开Lambda表达式,与lambda联合使用 ,方法引用可以使语言的构造更加紧凑简洁,减少冗余代码。

方法引用提供非常有用的语法,可以直接引用已有的java类或者对象中方法或者构造函数,方法引用需要配合Lambda表达式语法一起使用减少代码的冗余性问题。

//&#x65B9;&#x6CD5;&#x5F15;&#x5165;&#x5B9E;&#x9645;&#x4E0A;&#x5C31;&#x662F;lambda&#x8868;&#x8FBE;&#x5F0F;&#x4E2D;&#x76F4;&#x63A5;&#x5F15;&#x5165;&#x65B9;&#x6CD5;
//&#x65B9;&#x6CD5;&#x5F15;&#x5165;&#x89C4;&#x8303;&#xFF1A;[&#x5F15;&#x5165;&#x65B9;&#x6CD5;&#x7684;&#x53C2;&#x6570;&#x5217;&#x8868;&#x3001;&#x8FD4;&#x56DE;&#x7C7B;&#x578B;]&#x4E0E;[&#x51FD;&#x6570;&#x63A5;&#x53E3;&#x6570;&#x5217;&#x8868;&#x3001;&#x8FD4;&#x56DE;&#x7C7B;&#x578B;]&#x5FC5;&#x987B;&#x4FDD;&#x6301;&#x4E00;&#x81F4;

函数接口

Java8新特性2:Lambda表达式
方法引入Java8新特性2:Lambda表达式

Java8新特性2:Lambda表达式

Java8新特性2:Lambda表达式

2.5.2 静态方法引入

package com.yppah.myLambda.p7;

/**
 * @Author: haifei
 * @Date: 2022/10/27 14:46
 */
@FunctionalInterface
public interface MessageInterface {
    void get(Integer a);
}

package com.yppah.myLambda.p7;

/**
 * @Author: haifei
 * @Date: 2022/10/27 14:43
 */
public class Test09 {

    public static void main(String[] args) {
        // 1. 最原生的匿名内部类调用方式
        MessageInterface messageInterface = new MessageInterface() {
            @Override
            public void get(Integer a) {
                System.out.println("get a: " + a);
            }
        };
        messageInterface.get(1);

        // 2. lambda表达式改写上述
        MessageInterface messageInterface2 = a->System.out.println("get a: " + a);
        messageInterface2.get(2);

        // 新需求:在lambda表达式的方法体中直接引入方法
        MessageInterface messageInterface3 =(a) -> {
            Test09.getStatic(a);
        };
        messageInterface3.get(3);

        // 精简一下上述代码:方法引入
        // 3. 方法引入写法
        MessageInterface messageInterface4 = Test09::getStatic;
        messageInterface4.get(4);
        //方法引入实际上就是lambda表达式中直接引入方法
        //方法引入规范:[引入方法的参数列表、返回类型]与[函数接口数列表、返回类型]必须保持一致
    }

    public static void getStatic(Integer a) {
        System.out.println("getStatic a: "+ a);
    }
}

Java8新特性2:Lambda表达式

2.5.3 实例方法引入

package com.yppah.myLambda.p7;

/**
 * @Author: haifei
 * @Date: 2022/10/27 14:46
 */
@FunctionalInterface
public interface MessageInterface2 {
    String getMsg();
}

package com.yppah.myLambda.p7;

/**
 * @Author: haifei
 * @Date: 2022/10/27 16:08
 */
public class Test10 {

    public static void main(String[] args) {
//        MessageInterface2 messageInterface2 = ()->{return "999"};
        MessageInterface2 mi2 = ()->"999";
        System.out.println(mi2.getMsg()); //999

        Test10 test10 = new Test10();

        MessageInterface2 mi22 = ()->test10.objGet(); //lambda表达式方式
        System.out.println(mi22.getMsg()); //2222

        MessageInterface2 mi23 = test10::objGet; //方法引入方式
        System.out.println(mi23.getMsg()); //2222
    }

    public String objGet() {
        return "2222";
    }
}

2.5.4 构造方法引入

package com.yppah.myLambda.p7;

/**
 * @Author: haifei
 * @Date: 2022/10/27 16:20
 */
public class Message {

    private String msgId;
    private String msgName;

    public Message() {
    }

    @Override
    public String toString() {
        return "Message{" +
                "msgId='" + msgId + '\'' +
                ", msgName='" + msgName + '\'' +
                '}';
    }
}

package com.yppah.myLambda.p7;

/**
 * @Author: haifei
 * @Date: 2022/10/27 14:46
 */
@FunctionalInterface
public interface MessageInterface3 {
    Message getMsg();
}

package com.yppah.myLambda.p7;

/**
 * @Author: haifei
 * @Date: 2022/10/27 16:22
 */
public class Test11 {

    public static void main(String[] args) {
        MessageInterface3 mi3 = ()->{
            return new Message();
        };
        System.out.println(mi3.getMsg()); //Message{msgId='null', msgName='null'}

        //语法
        //函数接口返回类型::new
        MessageInterface3 mi32 = Message::new;
        System.out.println(mi32.getMsg()); //Message{msgId='null', msgName='null'}
    }
}

2.5.5 对象方法引入

package com.yppah.myLambda.p7;

/**
 * @Author: haifei
 * @Date: 2022/10/27 16:40
 */
public interface TestService {
    String get(Test12 test12);
}

package com.yppah.myLambda.p7;

/**
 * @Author: haifei
 * @Date: 2022/10/27 16:40
 */
public class Test12 {
    public static void main(String[] args) {
        // 方式1:匿名内部类
        TestService testService = new TestService() {
            @Override
            public String get(Test12 test12) {
                return test12.objGet();
            }
        };
        System.out.println(testService.get(new Test12())); //nbgeigei

        // 方式2:lambda表达式
        TestService testService2 = test12 -> test12.objGet();
        System.out.println(testService2.get(new Test12())); //nbgeigei

        // 方式3:方法引入
        // 方式3中的Test12::objGet相当于方式2中的test12 -> test12.objGet()
        TestService testService3 = Test12::objGet;
        System.out.println(testService3.get(new Test12())); //nbgeigei
    }

    public String objGet() {
        return "nbgeigei";
    }
}

案例:

package com.yppah.myLambda.p7;

import java.util.function.Function;

/**
 * @Author: haifei
 * @Date: 2022/10/27 16:56
 */
public class Test13 {

    public static void main(String[] args) {
        //需求: 利用JAVA内置的Function函数接口求字符串长度

        // 方式1:lambda
        Function function = str->str.length();
        System.out.println(function.apply("123456")); //6

        // 方式2:方法引用
        Function function2 = String::length;
        System.out.println(function2.apply("654321")); //6
    }
}

方法引入详见置顶链接

Original: https://www.cnblogs.com/yppah/p/16479674.html
Author: yub4by
Title: Java8新特性2:Lambda表达式

原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/571298/

转载文章受原作者版权保护。转载请注明原作者出处!

(0)

大家都在看

  • 线程池如何保证核心线程一直存活

    转载请注明出处: 查看 ThreadPoolExecutor 类中的 getTask 方法,这个方法可以保持核心线程在没有任务的时候也可以一直处于存活状态 核心在于 workQue…

    Java 2023年5月30日
    0153
  • java多线程2

    我们知道,线程有五种生命周期:新建,就绪,运行,阻塞,死亡. 在我们编写,运行代码的过程中,可能出现线程死锁,线程阻塞等问题,下面介绍线程产生这些问题的原因,及解决的方案,保证线程…

    Java 2023年6月8日
    083
  • SpringCloud Config 配置文件格式

    格式必须是 application-profiles ,如 application-dev.yml如果写成 application.yml ,通过 /application.yml…

    Java 2023年6月15日
    082
  • java和spring 线程池总结

    线程的使用在java中占有极其重要的地位,在jdk1.4极其之前的jdk版本中,关于线程池的使用是极其简陋的。在jdk1.5之后这一情况有了很大的改观。Jdk1.5之后加入了jav…

    Java 2023年5月29日
    073
  • Spring Boot使用AOP实现REST接口简易灵活的安全认证

    我们继续上一篇文章的分析,本文将通过AOP的方式实现一个相对更加简易 灵活的API安全认证服务。 我们先看实现,然后介绍和分析AOP基本原理和常用术语。 一、Authorized实…

    Java 2023年5月30日
    097
  • LeetCode.1185-一周中的星期几(Day of the Week)

    这是小川的第 415次更新,第 448篇原创 看题和准备 今天介绍的是 LeetCode算法题中 Easy级别的第 266题(顺位题号是 1185)。给定日期,返回该日期的星期几。…

    Java 2023年6月5日
    082
  • 合并链表

    404. 抱歉,您访问的资源不存在。 可能是网址有误,或者对应的内容被删除,或者处于私有状态。 代码改变世界,联系邮箱 contact@cnblogs.com 园子的商业化努力-困…

    Java 2023年6月5日
    077
  • java 实现字符串转换为树

    import java.util.*; class Node { public static void main(String[] args) { ArrayList listOf…

    Java 2023年6月5日
    082
  • JavaWeb 11_文件上传

    一、操作步骤 1、要有一个form标签,method=post 请求2、form标签的encType属性值必须为multipart/form-data值3、在form标签中使用in…

    Java 2023年6月7日
    055
  • [学习标准库]assert.h

    打算趁留在学校的最后一段时间好好补习一下一直以来都忽略掉的C/C++标准库,大概就是以头文件为单位了。以一个最简单的头文件入手,然后逐渐展开来……第一个头文…

    Java 2023年6月5日
    072
  • 0、编程入门

    0、编程入门 1、概述 计算机包括硬件和软件两部分。 硬件:可看见的物理部分; 软件:看不见的指令。 程序设计 定义:开发软件。 应用场景:淘宝、京东等软件。 程序设计语言 帮助开…

    Java 2023年6月13日
    071
  • Java面向对象之各种变量详解

    在Java中一定有很多变量让大家头疼,成员变量、类变量、局部变量等等,今天就来分别认识认识他们吧! Java面向对象之各种变量详解 前言 在 Java语言中, 根据定义变量位置的不…

    Java 2023年6月7日
    079
  • SpringBoot在Tomcat部署war包

    启动类配置 继承SpringBootServletInitializer @SpringBootApplication public class TestApplication e…

    Java 2023年6月15日
    095
  • 若依(ruoyi)代码生成树表结构的那些坑

    若依(RuoYI)代码生成树表结构的那些坑 相信许多做后端开发的同学,一定用过若依这款框架,这款框架易上手,适合用来做后台管理系统,但是其中也存在一些坑,稍不注意就会中招(大佬可以…

    Java 2023年6月15日
    087
  • Java开发学习(六)—-DI依赖注入之setter及构造器注入解析

    一、DI依赖注入 首先来介绍下Spring中有哪些注入方式? 我们先来思考 向一个类中传递数据的方式有几种? 普通方法(set方法) 构造方法 依赖注入描述了在容器中建立bean与…

    Java 2023年5月29日
    0107
  • 基于监控服务打造微服务治理生态体系

    基于上一篇《微服务海量日志监控平台》介绍的平台架构,继续架构的优化和能功的扩展,实现服务治理能力。 问题现状态 日志监控平台为我们带来了很多排查解决线上问题的便利。但是从某种程度上…

    Java 2023年6月6日
    098
亲爱的 Coder【最近整理,可免费获取】👉 最新必读书单  | 👏 面试题下载  | 🌎 免费的AI知识星球