Java中Lambda表达式(初学到精通)

news2024/12/23 1:13:34

目录

一、Lambda表达式是什么?什么场景下使用Lambda?

1.Lambda 表达式是什么

2.函数式接口是什么

 第二章、怎么用Lambda

1.必须有一个函数式接口

2.省略规则

3.Lambda经常用来和匿名内部类比较

   第三章、具体使用举例()

1.案例一,自己写简单Lambda表达式(自定义的函数式接口)

2.案例二,Lambda表达式创建线程(Runnable函数式接口)

3.案例三,Lambda表达式写判断型接口(Predicate函数式接口)

 4.案例四,Lambda表达式写比较器(Comparator函数式接口)

 5.案例五,Lambda表达式写过滤器(FileFilter函数式接口)

一、Lambda表达式是什么?什么场景下使用Lambda?


1.Lambda 表达式是什么


1.Lambda 表达式本质上是一个匿名方法,是JAVA8中提供的一种新的特性(一种新的表达方式,以前旧的写法换成新的写法,可以写出更简洁、更灵活的代码)。

我们以前定义一个方法总是想到方法的五要素:

修饰符 返回值类型 方法名(参数列){方法体}

2.我要打印一段话,用Lambda翻新成一个匿名方法,语法格式如下:

以前写个方法:
public void prin(){
System.out.println(" 打印这个Lambda啊");
}

现在用Lambda写:
最简单的三要素:
参数列表   操作符箭头   方法体
  ()         ->    {System.out.println(" 打印这个Lambda啊");}

注意:直接把下面这段拿去运行是不行的,忍住先往下看:

() -> { System.out.println(" 打印这个Lambda啊");}

在这个基础上我们进行拓展丰富,在参数列表里放一个参数。

注意:这个也不能运行

有一个参数,并且无返回值;
参数列表里放个参数a       操作符箭头        方法体
    (参数a)              ->        System.out.println(a);

继续丰富,在参数列表里放两个参数,有返回值。

注意1:前面多了个Comparator com = 

注意2:可以复制运行了。因为这段代码前面多了一个Comparator com =,这Comparator是个接口,而且是函数式接口,那么函数式接口是什么。

//有两个以上的参数,有返回值,并且大括号方法体里头多条语句
Comparator com = (a, b) -> {
System.out.println("打印一下");  return Integer.compare(10, 11);
};

2.函数式接口是什么

接口好理解,那什么是函数式接口呢?函数式接口是有且仅有一个抽象方法(不包含object中的方法)的接口。注意:我们只需要关注抽象方法的个数,不用关注其他类型的方法个数。

如图:我们可以用注解@FunctionalInterface 检测是否为函数式接口

 
第二章、怎么用Lambda

1.必须有一个函数式接口

看了第一章我们知道,Lambda表达式前面放普通接口是不行的,必须是Comparator 这种函数式接口。如图Collection接口不是函数式接口,报错了:

 把Collection接口换成函数式接口Consumer 就可以复制运行了。

//Consumer 是函数式接口
Consumer con = (x) -> System. out .println(x);
        con.accept( "这个可以运行打印了" );

2.省略规则

       1. 参数类型必须同时省略

       2. 一个参数时,参数的括号可省略

       3. 代码块里只有一句时,可省略大括号,分号和return

Comparator com = (x, y) -> Integer.compare(10, 13);

3.Lambda经常用来和匿名内部类比较

但注意

1.Lambda表达式虽然简洁,用()->就可以代替整个匿名内部类,但只能用于函数式接口(有仅只有一个抽象方法的接口)。匿名内部类却可以用于接口,抽象类或者普通类。举个函数式接口Runnable接口的例子:


        new Thread(new Runnable() {
            @Override
            public void run() {
                System.out.println("这是匿名内部类里传了个Runnable的实现类对象");
            }
        }).start();
    

用Lambda写一下


 new Thread(() -> System.out.println("好家伙这么简洁")).start();

   第三章、具体使用举例()

我们要明确方法体才是关键所在,Lambda表达式方法体里的方法来自哪个函数式接口,这个接口的抽象方法作用是什么,才能有明确的目的去写Lambda表达式,也就是我们说的:“解决什么问题”。

1.案例一,自己写简单Lambda表达式(自定义的函数式接口)

1.自己写一个函数式接口注意只能有一个抽象方法,

public interface Test {
//有且仅有一个抽象方法
    public String TestFunc(String test_str);
}

2.Lambda表达式:把字符串传入箭头符号右边的方法体

   Test test =(str)->{ System.out.println(str); return str;};
        String str=test.TestFunc("打印这个字符串");
        
   }

2.案例二,Lambda表达式创建线程(Runnable函数式接口)

明确作用和方法:

1.Runnable接口,Runnable 为非 Thread 子类的类提供了一种激活方式。把Runnable的实例传给Thread 实例并将自身作为运行目标,就可以运行实现 Runnable 的类而无需创建 Thread 的子类。

唯一的抽象方法run()
          使用实现接口 Runnable 的对象创建一个线程时,启动该线程将导致在独立执行的线程中调用对象的 run 方法
// 匿名内部 类
        new Thread(new Runnable() {
            @Override
            public void run() {
                System.out.println("匿名对象 传递线程任务.....");
            }
        }).start();

2.再用Lambda表达式写

/*Lambda表达式 省略格式
1. 参数类型必须同时省略
2. 一个参数时,参数的括号可省略
3. 代码块里只有一句时,可省略大括号,分号和return  */

new Thread(() -> System.out.println("Lambda表达式 启动线程...")).start();

3.案例三,Lambda表达式写判断型接口(Predicate函数式接口)

明确作用和方法:Predicate判断型接口,可以对数据进行条件的判断,返回判断的结果。

唯一抽象方法 boolean test​(T t)

在给定的参数上进行条件评估。

演示:1.第一步先创建集合list

  //先创建一个集合
ArrayList<Integer> list = new ArrayList<>();
  //使用addAl方法添加元素
    Collections.addAll(list, 1, 2, 3, 4, 5, 6, 7, 8, 9);

2.用list调用removeIf()方法,

方法介绍: default boolean removeIf​(Predicate<? super E> filter) ,删除集合中满足给定条件的元素

注意:因为removeIf()参数列表里需要传递的是函数式接口Predicate实例

所以我们可以在方法的括号里头,用上匿名内部类写法;在大括号里重写这个唯一的抽象方法。

 // 删除集合中的偶数  default boolean removeIf​(Predicate<? super E> filter) 删除满足给定谓词的此集合的所有元素。
        list.removeIf(new Predicate<Integer>() {
            @Override
            public boolean test(Integer integer) {
                return integer % 2 == 0;
            }
        });
        System.out.println(list);

3.在前面我们提到Predicate接口是函数式接口,所以我们自然可以用Lambda重写一次

//不省略格式
    list.removeIf( (Integer itgr) -> { return itgr % 2 == 0;});

//省略写法 
// 1.一个参数把括号和参数类型     省略
// 2.只有一条方法语句把大括号{}和; return 省略

    list.removeIf(  itgr -> itgr % 2 == 0);
//打印集合
    System.out.println(list);

 4.案例四,Lambda表达式写比较器(Comparator函数式接口)

明确作用和方法:Comparator函数式接口,强行对某个对象 collection 进行整体排序 的比较函数。可以将 Comparator实例 传递给 sort 方法(如 Collections.sortArrays.sort),从而允许在排序顺序上实现精确控制。

唯一的抽象方法compare(T o1, T o2)
          比较用来排序的两个参数

演示:

1.创建集合加入元素

 // 创建集合使用addAll()方法加入元素

        ArrayList<Integer> list = new ArrayList<>();
        Collections.addAll(list, 1, 3, 2, 4, 5, 7, 9, 8, 6);

        // 先用sort(list)方法进行  升序 排序
        Collections.sort(list);
        System.out.println(list);

2.注意:因为参数列表里需要传递的参数类型是函数式接口Comparator

所以我们可以在sort()方法的括号里头,用上匿名内部类写法;在里头重写这个唯一的抽象方法compare()


//匿名内部类  写降序排序,Collections.sort(List<T> list, Comparator<? super T> c)
        
Collections.sort(list, new Comparator<Integer>() {
            @Override
            public int compare(Integer o1, Integer o2) {
                return o2 - o1;
            }
        });



      

3.用Lambda重写一下

//lambda表达式写 降序排序
// Collections.sort(list,(Integer o1, Integer o2)->{ return o2 - o1;});
// 简化格式,两个参数类型一样省略参数类型但是括号不能省略,方法体只一条语句省略{};return
    Collections.sort(list,(o1,o2)->  o2 - o1);
     System.out.println(list);

 5.案例五,Lambda表达式写过滤器(FileFilter函数式接口)

明确作用和方法:抽象路径名的过滤器。该接口的实例可以传递给File类的listFiles(FileFilter)方法。

FileFilter接口的唯一抽象方法accept​(File pathname)

测试指定的抽象路径名是否应包含在路径名列表中。    

File类的listFiles​(FileFilter filter)方法介绍:

返回一个抽象路径名数组,表示由此抽象路径名表示的满足指定过滤器的目录中的文件和目录。

演示1:

1.先用匿名内部类写

 // 创建文件对象,文件路径是d:\\demo
        File file = new File("d:\\demo");
        // file调用listFiles()直接传入过滤器的实例和pathname,返回类型是数组
        File[] files = file.listFiles(new FileFilter() {
            @Override
            public boolean accept(File pathname) {
                //endsWith(".txt") 获取以.txt结尾,并且只要是文件,
                return pathname.getName().endsWith(".txt") && pathname.isFile();
            }
        });

2.用Lambda写

//这是未简化
File[] files1 = file.listFiles((File pathname)->{return pathname.isFile() && pathname.getName().endsWith(".txt");});

//简化格式后
        File[] files1 = file.listFiles( pathname -> pathname.isFile() && pathname.getName().endsWith(".txt") );

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

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

相关文章

跳跃游戏类题目 总结篇

一.跳跃游戏类题目简单介绍 跳跃游戏是一种典型的算法题目&#xff0c;经常是给定一数组arr&#xff0c;从数组的某一位置i出发&#xff0c;根据一定的跳跃规则&#xff0c;比如从i位置能跳arr[i]步&#xff0c;或者小于arr[i]步&#xff0c;或者固定步数&#xff0c;直到到达某…

C++ 链表概述

背景 当需要存储大量数据并需要对其进行操作时&#xff0c;常常需要使用到链表这种数据结构。它可以用来存储一系列的元素并支持插入、删除、遍历等操作。 概念 一般来说&#xff0c;链表是由若干个节点组成的&#xff0c;每个节点包含了两个部分的内容&#xff1a;存储的数…

【嵌入式环境下linux内核及驱动学习笔记-(6-内核 I/O)-阻塞与非阻塞】

目录 1、阻塞与非阻塞1.1 以对recvfrom函数的调用及执行过程来说明阻塞的操作。1.2 以对recvfrom函数的不断轮询调用为例&#xff0c;说明非阻塞时进程的行为。1.3 简单介绍内核链表及等待队列1.4 等待队列1.4.1 定义等待队列头部&#xff08;wait_queue_head_t&#xff09;1.4…

vue动态添加多组数据添加正则限制

如图新增多条数据&#xff0c;如果删除其中一条正则校验失败的数据&#xff0c;提示不会随之删除&#xff0c;若想提示删除并不清空数据 delete (item, index) {this.applicationForm.reserveInfo.forEach((v, i) > {if (i index) {this.$refs.formValidate.fields.forEac…

UFT——操作模块

示例一 创建一个可重复利用的登录测试更改Action的名称。使用本地数据表。创建一个主调用测试。建立测试迭代。处理缺失的Action。 分析&#xff1a;就是创建一个只有登录的测试起名为login&#xff0c;然后在创建一个主测试起名字比如main&#xff0c;在main中&#xff0c;调用…

微信小程序定义模板

微信小程序提供模板&#xff08;template&#xff09;功能&#xff0c;把一些可以共用的&#xff0c;复用的代码在模板中定义为代码片段&#xff0c;然后在不同的地方调用&#xff0c;可以实现一次编写&#xff0c;多次引用的效果。 首先我们看一下官网是如何操作的 一般的情…

笔记:对多维torch进行任意维度的多“行”操作

如何取出多维torch指定维度的指定“行” 从二维torch开始新建torch取出某一行取出某一列一次性取出多行取出连续的多行取出不连续的多行 一次取出多列取出连续的多列取出不连续的多列 考虑三维torch取出三维torch的任意两行&#xff08;means 在dim0上操作&#xff09;取出连续…

( 字符串) 9. 回文数 ——【Leetcode每日一题】

❓9. 回文数 难度&#xff1a;简单 给你一个整数 x &#xff0c;如果 x 是一个回文整数&#xff0c;返回 true &#xff1b;否则&#xff0c;返回 false 。 回文数是指正序&#xff08;从左向右&#xff09;和倒序&#xff08;从右向左&#xff09;读都是一样的整数。 例如…

Git的安装与使用+Git在IDEA中的使用

文章目录 一、Git概述1、版本控制器的方式2、Git的工作流程图 二、Git的安装与常用命令1、Git环境安装2、Git环境基本配置3、获取本地仓库4、基础操作指令 三、分支1、常用指令2、解决合并冲突 四、Git远程仓库1、创建远程仓库2、远程操作仓库3、冲突处理 四、IDEA中使用Git1、…

数据结构——二叉树

二叉树 1 二叉树的种类 1.1 满二叉树 节点数量为 2^k - 1 (k是树的深度&#xff0c;底层的叶子节点都是满的&#xff09; 1.2 完全二叉树 完全二叉树是指除了下面一层外&#xff0c;其余层的节点都是满的&#xff1b; 且最下面一层的叶子节点是从左到右连续的。 下面这个…

pci总线协议学习笔记——PCI总线基本概念

1、pci总线概述 (1)PCI&#xff0c;外设组件互连标准(Peripheral Component Interconnection)&#xff0c;是一种由英特尔&#xff08;Intel&#xff09;公司1991年推出的用于定义局部总线的标准; (2)最早提出的PCI总线工作在33MHz频率之下&#xff0c;传输带宽达到133MB/s(33M…

【LeetCode】236. 二叉树的最近公共祖先

1.问题 给定一个二叉树, 找到该树中两个指定节点的最近公共祖先。 百度百科中最近公共祖先的定义为&#xff1a;“对于有根树 T 的两个节点 p、q&#xff0c;最近公共祖先表示为一个节点 x&#xff0c;满足 x 是 p、q 的祖先且 x 的深度尽可能大&#xff08;一个节点也可以是…

1992-2022年31省GDP、第一产业增加值、第二产业增加值 第三产业增加值

1992-2022年31省GDP、第一产业增加值、第二产业增加值 第三产业增加值 1、时间&#xff1a;1992-2022年 2、范围&#xff1a;包括31省 3、指标&#xff1a;省GDP、省第一产业增加值、省第二产业增加值、省第三产业增加值 4、缺失情况说明&#xff1a;无缺失 5、来源&#…

【python知识】__init__.py的来龙去脉

一、说明 我们常见__init__.py文件&#xff0c;但说不清楚它的用途&#xff0c;在本文&#xff0c;我将首先把它的来龙去脉说清楚&#xff0c;然后告诉大家&#xff0c;如何编制python工程&#xff0c;培养全局的编程格局。 二、包-模块-函数结构 在Python工程里&#xff0c;当…

playwright连接已有浏览器操作

文章目录 playwright连接已有浏览器操作前置准备打开本地已有缓存的Chrome&#xff08;理解&#xff09;指定端口打开浏览器连接指定端口已启动浏览器&#xff08;推荐&#xff09; playwright连接已有浏览器操作 前置准备 pip install playwright # 安装playwright的python…

红黑树数据结构

现在JAVASE中HashMap中底层源码是由数组链表红黑树进行设计的&#xff0c;然后很多地方也是用到红黑树&#xff0c;这里单独对红黑树数据结构进行简单的介绍。 目录 红黑树概念 红黑树的性质 自平衡规则 代码 红黑树概念 红黑树&#xff0c;是一种二叉搜索树&#xff0c;…

linux常用命令大全(保姆及入门)

linux常用命令大全 一、文件处理命令1、目录处理命令&#xff1a;ls2、目录处理命令2.1 mkdir2.2 pwd2.3 rmdir2.4 cp2.5 mv2.6 rm 3.文件处理命令3.1 touch3.2 cat3.3 tac3.4 more3.5 less3.6 head3.7 tail 4.链接命令4.1 ln 二、权限管理命令2.1 chmod2.2 chown2.3 chgrp 2.4…

VRPTW:新雀优化算法NOA求解带时间窗的车辆路径问题

一、新雀优化算法NOA求解带时间窗的车辆路径问题 1.1VRPTW模型如下&#xff1a; 带时间窗的车辆路径问题(Vehicle Routing Problem with Time Windows, VRPTW) 1.2新雀优化算法NOA求解VRPTW close all clear clc SearchAgents_no30; % 种群大小 Function_nameF1; Max_ite…

准备“开黑”,电脑却“告退”?游戏闪退的解决方法

游戏玩家近期可能会发现&#xff0c;不少大作陆陆续续登录PC市场&#xff0c;比如《死亡岛 2》、《无畏契约》等。但也有不少游戏用户会发现&#xff0c;电脑玩游戏时容易出现闪退的情况。特别是在进行高负荷运算的时候&#xff0c;有一些游戏更为容易出现这种情况&#xff0c;…