Lambda表达式了解到使用(清晰明朗)

news2024/11/17 2:54:42

这里写目录标题

  • lambda简述
  • 以前的实现
  • 初次使用lambda表达式
  • Lambda表达式的语法
    • 测试方法
  • lambda表达式简写示范
    • 测试方法
    • 运行结果
  • 方法引用
    • 测试方法
    • 运行结果
  • 构造方法引用
    • 定义一个Boy类
    • 编写测试方法
    • 运行结果
  • 实际应用
    • 测试代码
    • 运行结果
    • 内置函数式接口
  • @FunctionalInterface注解
    • @FunctionalInterface注解简介
    • @FunctionalInterface注解特点

lambda简述

可以把Lambda表达式理解为一段可以传递的代码,可以写出更简洁、更灵活的代码。Lambda表达式是JAVA8中提供的一种新的特性,是一个匿名函数方法。

以前的实现

匿名内部类,调用执行,实际上核心的功能只有一行语句System.out.println(i+j);代码比较庞大

public class test01 {
    public static void main(String[] args) {
        A a=new A() {
            @Override
            public void add(int i, int j) {
                System.out.println(i+j);
            }
        };
        a.add(10,15);
    }
}
interface A{
   void add(int i,int j);
}

初次使用lambda表达式

public class test02 {
    public static void main(String[] args) {
        A a=(int i,int j)->{
            System.out.println(i+j);
        };
        a.add(10,15);
    }
}
interface A{
    void add(int i,int j);
}

Lambda表达式的语法

Lambda表达式如果要想使用,应该是函数式接口。函数式接口首先必须是一个接口,接口里面只能有一个抽象方法(允许有默认方法、静态方法等);这种类型的接口也称为SAM接口,即Single Abstract Method Interface。
Lambda表达式语法:
(int a,int b) ->{return a+b;};
这个本质是一个函数;
Lambda表达式函数的话,只有参数列表,和方法体;
( 参数列表 ) -> { 方法体 }
( ) :参数列表;
{ } :方法体;
-> :Lambda运算符,可叫做箭头符号
一般的函数是定义是

int add(int ii,int j){
  return i+j;
}

有返回值,方法名,参数列表,方法体
Lambda表达式的语法示例
下面定义了几种不同的接口,并书写了他们的lambda表达式
无参数无返回值,单个参数无返回值,两个参数无返回值,无参数有返回值:int, 单个参数有返回值:int,多个参数有返回值:int

测试方法

public class test03{
    public static void main(String[] args) {
        // 无参数无返回值
        A a=()->{
            System.out.println("无参数无返回值");
        };
        a.test();

// 单个参数无返回值
        B b=(int i)->{
            System.out.println("单个参数无返回值 i="+i);
        };
        b.test(3);

// 两个参数无返回值
        C c=(int i,int j)->{
            System.out.println("两个参数无返回值 i+j="+(i+j));
        };
        c.test(10,15);

// 无参数有返回值:int
        D d=()->{
            System.out.print("无参数有返回值 ");
            return 100;
        };
        System.out.println(d.test());


// 单个参数有返回值:int
        E e=(int i)->{
            System.out.print("单个参数有返回值i= ");
            return i;
        };
        System.out.println(e.test(520));

// 多个参数有返回值:int
        F f=(int i,int j)->{
            System.out.print("多个参数有返回值i-j=");
            return i-j;
        };
        System.out.println(f.test(10,80));
    }
}
interface A{
// 无参数无返回值
    void test();
}
interface B{
    //单个参数无返回值
    void test(int i);
}
interface C{
    // 两个参数无返回值
    void test(int i,int j);
}
interface D{
    // 无参数有返回值
    int test();
}
interface E{
    //单个参数有返回值
    int test(int i);
}
interface F{
    //多个参数有返回值
    int test(int i,int j);
}

lambda表达式简写示范

lambda 表达式形式为 ()->{},-> 左边是形参列表, -> 右边是实现体。
lambda 方法如果没有参数或有两个及以上的参数,则 小括号不能省略。
lambda 方法可以省略参数的类型,可以通过上下文进行推断。
lambda 方法如果只有一个参数,则小括号可以省略。
lambda 方法体如果只有一行语句,则 大括号和return都可省略。
省略了大括号,则必须省略 return,省略了 return ,则必须省略 {},这俩要么成对出现,要么都不出现

测试方法

public class test04{
    public static void main(String[] args) {
/**   1,参数类型可以省略
      2,假如只有一个参数,()括号可以省略
      3,如果方法体只有一条语句,{}大括号可以省略
      4,如果方法体中唯一的语句是return返回语句,那省略大括号的同事return也要省略
 */
        // 无参数无返回值
        //省略了花括号
        A a=()-> System.out.println("无参数无返回值");
        a.test();

// 单个参数无返回值
        //省略了花括号和小括号和参数类型
        B b=i-> System.out.println("单个参数无返回值 i="+i);
        b.test(3);

// 两个参数无返回值
        //省略了花括号和参数类型
        C c=(i,j)-> System.out.println("两个参数无返回值 i+j="+(i+j));
        c.test(10,15);

// 无参数有返回值:int
        //省略了花括号和参数类型
        D d=()->{
            System.out.print("无参数有返回值 ");
            return 100;
        };
        System.out.println(d.test());

// 单个参数有返回值:int

//    E e=(int i)->{
//           System.out.print("单个参数有返回值i= ");
//           return i;
//      };
        //为示范方法体只有一个return语句
        // 先把sout语句删除掉只保留一个return语句
        //只有一个参数先省略了参数类型和小括号,只有一条语句省略花括号和return关键字
        E e=i->i;
        System.out.println("单个参数有返回值i="+e.test(520));

// 多个参数有返回值:int
        F f=( i,j)->{
            System.out.print("多个参数有返回值i-j=");
            return i-j;
        };
        System.out.println(f.test(10,80));
    }
}
interface A{
    // 无参数无返回值
    void test();
}
interface B{
    //单个参数无返回值
    void test(int i);
}
interface C{
    // 两个参数无返回值
    void test(int i,int j);
}
interface D{
    // 无参数有返回值
    int test();
}
interface E{
    //单个参数有返回值
    int test(int i);
}
interface F{
    //多个参数有返回值
    int test(int i,int j);
}

运行结果

在这里插入图片描述

方法引用

有时候多个lambda表达式实现函数是一样的话,我们可以封装成通用方法,以便于维护;
这时候可以用方法引用实现
语法:
static方法 类名::方法名
普通方法 对象名::方法名

测试方法

public class test05 {
    public static void main(String[] args) {
        test05 t5=new test05();
        // 普通方法 对象名::方法名
        F f1=t5::test01;
        System.out.println("普通方法 对象名::方法名   "+f1.test(10,80));
        // static方法 类名::方法名
        F f2 = test05::test02;
        System.out.println("static方法 类名::方法名   "+f2.test(10, 80));
    }
    public int test01(int i,int j){
        return i+j;
    }
    public static int test02(int i,int j){
        return i-j;
    }
}

interface F {
    //多个参数有返回值
    int test(int i, int j);
}

运行结果

在这里插入图片描述

构造方法引用

如果函数式接口的实现恰好可以通过调用一个类的构造方法来实现,
那么就可以使用构造方法引用;
语法:类名::new

定义一个Boy类

public class Boy {
    private String name;
    private int age;
    private String hobby;
    public  Boy(){
        System.out.println("这是Boy类的无参构造方法");
    }
    public Boy(String name,int age,String hobby){
        System.out.println("这是Boy类的有参构造方法");
        this.name=name;
        this.age=age;
        this.hobby=hobby;
    }

    public int getAge() {
        return age;
    }

    @Override
    public String toString() {
        return "Boy{" +
                "name='" + name + '\'' +
                ", age=" + age +
                ", hobby='" + hobby + '\'' +
                '}';
    }
}

编写测试方法

import com.sun.xml.internal.ws.api.model.wsdl.WSDLOutput;

public class test06 {
    public static void main(String[] args) {
        //一般写法
//        A a=()->{
//            return new Boy();
//        };
//        System.out.println(a.getBoy());
//
//        B b=(String name,int age,String hobby)->{
//            return new Boy( name, age,hobby);
//        };
//        System.out.println(b.getBoy("cxk", 888,"篮球"));
            
        //构造方法引用写法
        A a=Boy::new;
        System.out.println(a.getBoy());

        B b=Boy::new;
        System.out.println(b.getBoy("cxk", 888,"篮球"));

    }
}
interface A{
    Boy getBoy();
}
interface B{
    Boy getBoy(String name,int age,String hobby);
}

运行结果

在这里插入图片描述

实际应用

我们可以通过lambda表达式来排序集合中的元素,在sort方法中有一个接口Comparator接口,Comparator接口有个compare抽象方法传入两个参数,返回一个整型数字,我们可以通过该方法实现对集合的排序。
sort方法里有一个Comparator接口
在这里插入图片描述
Comparator接口有个compare方法,我们可以通过该方法实现对集合的排序

在这里插入图片描述
在这里插入图片描述
我们还可以通过lambda表达式来遍历集合,forEach方法中有消费者Consumer接口,接口里有个接口参数的accept的方法,传入值而不返回任何参数。
再看下集合的forEach方法,点进去:
在这里插入图片描述
有个消费者Consumer接口,再点进去:
在这里插入图片描述
接口里有个接口参数的accept的方法;
所以我们直接方法引用 直接输出每次的遍历值即可;
System.out::println

测试代码

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

public class test07 {

    public static void main(String[] args) {
        List<Boy> list=new ArrayList<>();
        list.add(new Boy("张三",10,"乒乓球"));
        list.add(new Boy("王二",41,"篮球"));
        list.add(new Boy("李四",31,"网球"));
        list.add(new Boy("麻子",21,"吃饭"));
        list.add(new Boy("无名氏",25,"上网"));
        // 排序
        System.out.println("集合排序lambda方式");
        list.sort((o1,o2)->o1.getAge()-o2.getAge());
        System.out.println(list);

        //遍历集合
        System.out.println("遍历集合lambda方式(一般情况)");
        list.forEach(e-> System.out.println(e));

        // 遍历集合
        //方法引用由::双冒号操作符标示
        System.out.println("遍历集合lambda方式(方法引用)");
        list.forEach(System.out::println);
    }
}

运行结果

在这里插入图片描述

内置函数式接口

在java8中使用Lambda表达式时候,java已经内置了四大核心函数式接口,
分别是:1.消费型接口2.供给型接口3.函数型接口4.断言型接口
因此一些常用/简单的接口,用户可以不用自定义了,直接用系统提供的函数接口即可。

@FunctionalInterface注解

@FunctionalInterface注解简介

可以看到Consumer接口,Comparator接口都有@FunctionalInterface注解
Java8为函数式接口引入了一个新的注解@FunctionalInterface,主要用于编译级错误检查,加上该注解,当你写的接口不符合函数式接口的定义时,编译器会报错。
这个注解是函数式接口注解,所谓的函数式接口,当然首先是一个接口,然后就是在这个接口里面只能有一个抽象方法。
这种类型的接口也称为SAM接口,即Single Abstract Method interfaces

@FunctionalInterface注解特点

接口有且仅有一个抽象方法
允许定义静态方法
允许定义默认方法
允许java.lang.Object中的public方法
该注解不是必须的,如果一个接口符合"函数式接口"定义,不加该注解是没有影响的。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/339312.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

自从学会了Python,我实现了壁纸自由(6)

小朋友们好&#xff0c;大朋友们好&#xff01;我是猫妹&#xff01;哈哈哈&#xff0c;又到周末啦&#xff01;这周过得怎么样&#xff1f;马上就要开学了&#xff0c;寒假作业早已写好了吧&#xff1f;开学让人兴奋&#xff0c;上了很久网课都要吐啦&#xff01;开学也让人有…

HTTPS为什么就安全了?或者说要安全我们要做到什么?

目录 一 安全概念 二 HTTPS的安全措施 三 总结 一 安全概念 网络安全是一个比较笼统的概念。我们说网络安全的时候&#xff0c;往往会包含很多安全问题&#xff0c;包括网络设备层面、通信过程、数据本身等多方面引入的安全问题。比如设备被有意无意的破坏&#xff0c;链路…

【C/C++基础练习题】简单函数练习题

&#x1f349;内容专栏&#xff1a;【C/C要打好基础啊】 &#x1f349;本文内容&#xff1a;简单函数使用练习题&#xff08;复习之前写过的实验报告&#xff09; &#x1f349;本文作者&#xff1a;Melon西西 &#x1f349;发布时间 &#xff1a;2023.2.11 目录 1.给定某个年…

右键菜单管理 - Win系统

右键菜单管理 - Win系统前言软件工具管理右键菜单360右键管理右键管家前言 Windows系统可以借助软件工具对右键菜单进行管理&#xff0c;可对指定的右键菜单进行删除和恢复。下面以Win10系统为例介绍管理方法。 注意&#xff1a;使用本文提及的工具将某软件的右键菜单删除后&…

电子货架标签多种固定方式

2.1寸和2.9寸电子价格标签多种固定方式&#xff1a; 1、桌面支架&#xff0c;放置在桌面或是货架上&#xff0c;用于桌面产品的价格或是信息显示 2、粘贴架&#xff0c;方便用于墙面桌面等应用 3、半透明支架&#xff0c;用于货架上的商品吊挂显示价格信息 4、轨道架&#xff…

1489车厢调度(train)(栈)

目录 题目描述 解题思路&#xff1a; 代码部分&#xff1a; 题目描述 有一个火车站&#xff0c;铁路如图所示&#xff0c;每辆火车从A驶入&#xff0c;再从B方向驶出&#xff0c;同时它的车厢可以重新组合。假设从A方向驶来的火车有n节&#xff08;n≤1000&#xff09;&…

使用动态参数构建CUDA图

文章目录使用动态参数构建CUDA图使用显式 API 调用构建 CUDA 图使用流捕获构建 CUDA 图组合方法执行结果总结使用动态参数构建CUDA图 自从在 CUDA 10 以来&#xff0c;CUDA Graphs 已被用于各种应用程序。 上图将一组 CUDA 内核和其他 CUDA 操作组合在一起&#xff0c;并使用指…

shell编程之sed

文章目录八、shell编程之sed8.1 工作原理8.2 sed基本语法8.3 模式空间中的编辑操作8.3.1 地址定界8.3.2 常用编辑命令8.4 sed扩展八、shell编程之sed 8.1 工作原理 sed是一种流编辑器&#xff0c;它是文本处理中非常有用的工具&#xff0c;能够完美的配合正则表达式使用&…

图----无向图

1.定义 图的定义&#xff1a;图是由一组顶点和一组能够将两个顶点相连的边组成 边&#xff1a;edge 顶点&#xff1a;vertex 连通图&#xff1a;如果从任意一个顶点都存在一条路径到达另外一个任意顶点&#xff0c;我们称这幅图是连通图。 非连通图&#xff1a;由若干连通的…

【Python】tkinter messagebox练习笔记

我一好友在朋友圈看到人家用代码花式秀恩爱&#xff0c;让我也做一个&#xff0c;我就用我学习半年python的功力&#xff0c;做了这一个东西。&#x1f64f;窗口主页面&#xff08;图一&#xff09;为了让我这个盆友有颜面&#xff0c;特意做了一个问答问他帅不帅&#xff0c;以…

Active Directory 02 - Windows Kerberos Authentication(Kerberos 协议鉴权)

写在最前 如果你是信息安全爱好者&#xff0c;如果你想考一些证书来提升自己的能力&#xff0c;那么欢迎大家来我的 Discord 频道 Northern Bay。邀请链接在这里&#xff1a; https://discord.gg/9XvvuFq9Wb我会提供备考过程中尽可能多的帮助&#xff0c;并分享学习和实践过程…

从0到1一步一步玩转openEuler--11 openEuler基础配置-设置磁盘调度算法

11 openEuler基础配置-设置磁盘调度算法 文章目录11 openEuler基础配置-设置磁盘调度算法11.1 设置磁盘调度算法11.1.1 临时修改调度策略11.1.2 永久设置调度策略11.1 设置磁盘调度算法 本节介绍如何设置磁盘调度算法。 11.1.1 临时修改调度策略 例如将所有IO调度算法修改为…

js逆向-某头条_signature参数

前言 头条的加密参数_signature其实可以通过搜索来直接定位到关键位置&#xff0c;我们换种定位的方法 定位 先查看下堆栈&#xff0c;直接在第一个XMLHttpRequest.send的位置下上断点&#xff0c;然后下拉触发断点 这个位置还有其他请求&#xff0c;这里只看/api/pc/list…

2023 AIME 答案与解析 - 第二期(完结)

原题目 Find the number of cubic polynomials where and are integers in such that there is a unique integer with 绿树教育中心独家解析 是一个有两个整数根的三次方程&#xff0c;因此它有三个整数根。所以&#xff0c; 或 &#xff0c;其中 。 「Case 1」 &#xff0c;则…

关于spring bean的生命周期的个人理解(根据官方文档学习)

首先说一下Servlet的生命周期&#xff1a;实例化&#xff0c;初始init&#xff0c;接受service&#xff0c;销毁destroy&#xff1b; spring上下文中的Bean 生命周期也是类似&#xff0c;如下&#xff1a; &#xff08;1&#xff09;实例化Bean 对于Bean Factory容器&#xf…

elasticsearch更新和删除

文档更新文档的更新经历三个步骤&#xff0c;检索、修改、重新索引部分更新在原有文档已经存在的情况下&#xff0c;可以对原有的文档部分字段更新&#xff0c;使用POST请求&#xff0c;发送到/_update如果文档是不存在的&#xff0c;更新操作是失败的存在则更新&#xff0c;不…

Qt C++ 自定义仪表盘控件02

简介仪表盘是工控领域不可缺少的一类软件UI元素&#xff0c;通常出现在各类电子看板软件上&#xff0c;以及一些高级的上位机软件界面上&#xff0c;目的是将繁杂的数据转化为可视化的图表能大幅提高后台管理效率。本文分享了几个经典常用的仪表盘控件&#xff0c;在项目中可以…

利用升序定时器链表处理非活动连接

参考自游双《Linux高性能服务器编程》 背景 服务器同常需要定期处理非活动连接&#xff1a;给客户发一个重连请求&#xff0c;或关闭该连接&#xff0c;或者其他。我们可以通过使用升序定时器链表处理非活动连接&#xff0c;下面的代码利用alarm函数周期性的触发SIGALRM信号&a…

半人半妖时代来啦

未来是半人半妖时代&#xff01;&#xff01;&#xff01; 碳基生命与硅基生命结合 趣讲大白话&#xff1a;人和机器结合是大趋势 *********** 人工智能就是宗&#xff5e;教 科技宗&#xff5e;教的一支最强势的教派 日常使用智能机器的人就是信众 维护机器的人就是牧师 创造这…