Java20:新特性

news2024/11/13 22:16:22

一:Lambda表达式:

1. Lambda表达式使用前后对比:

举类一:

 @Test
  public void test(){
Runnable r1 = new Runnable() {
    @Override
    public void run() {
        System.out.println("我爱北京天安门!");
    }
};
     r1.run();
      System.out.println("******************************");
      //lambda表达式的写法
      Runnable r2=()->System.out.println("我爱北京天安门!");
      r2.run();
  }

举类二:

@Test
public void test2(){

    Comparator<Integer> com = new Comparator<Integer>() {
        @Override
        public int compare(Integer o1, Integer o2) {
            return Integer.compare(o1,o2);
        }
    };
    int compare = com.compare(12, 15);
    System.out.println(compare);
    System.out.println("******************************");
    //lambda表达式的写法
    Comparator<Integer> com2= (o1,o2)->Integer.compare(o1,o2);
    int compare1 = com2.compare(21, 15);
    System.out.println(compare1);

}
2.lambda表达式的基本语法

1.举类:(o1,o2)->Integer.compare(o1,o2);

2.格式:

       》lambda操作符或 箭头操作符

       》左边:lambda形参列表(其实就是接口的抽象方法的形参列表)

       》右边:lambda体(其实就是重写的抽象方法的方法体)

3.如何使用:分为六种情况:
//语法格式一:无参,无返回值
Runnable r1 =()-> {System.out.println("hello lambda");};
//语法格式二:一个参数,但是没有返回值
Consumer<String> con=(String str)-> {System.out.println(str);};
//语法格式三:数据类型可以省略,因为可由编译器推断出,称为“类型推断”
Consumer<String> con2=(str)-> {System.out.println(str);};
//语法格式四:只有一个参数时,参数的小括号可以省略
Consumer<String> con3=str-> {System.out.println(str);};
//语法格式五:需要两个或以上参数,多条执行语句,并且可以由返回值
Comparator<Integer> com =(o1,o2)->{
    System.out.println("实现函数式接口方法!");
    return Integer.compare(o1,o2);
};
//语法格式六:当lambda体只有一条执行语句时,return与大括号若有,都可以省略
Comparator<Integer> com2 =(o1,o2)->Integer.compare(o1,o2);
4.总结六种情况:

》左边:lambda形参列表的参数类型可以省略(类型推断):如果lambda形参列表

只一个参数,其一对()也可以省略

》右边:lambda 体应该使用一对{}包裹;如果lambda体只一条执行语句(可能是return语句,省略这一对{}和return关键字)

二:函数式接口:

1.函数式接口的使用说明

》如果一个接口中,只声明一个抽象方法,则此接口就称为函数式接口。我们可以

》在一个接口上使用@FunctionalInterface 注解,这样做可以检查它是否是一个函数式接口。

》lambda表达式的本质:作为函数式接口的实例

2.java8中关于lambda表达式提供的4个基本的函数式接口:

具体使用:

3.总结:

3.1何时使用lambda表达式?

当需要对一个函数式接口实例化的时候,可以使用lambda表达式。

3.2 何时 使用给定的函数式接口?

如果我们开发中需要定义一个函数式接口,首先看看在已有的jdk提供的函数式接口是否提供了

能满足需求的函数式接口。如果有则直接调用即可,不需要自己再定义了。

三:方法引用:

1.理解:

方法引用可以看做式lambda表达式深层次的表达,换句话说,方法引用就是lambda表达式,

也就是函数式接口的一个实例:通过方法的名字来指向一个方法。

2.使用情境:

当要传递给lambda体的操作,已经有实现的方法了,可以使用方法引用。

3.格式:

类(或对象)::方法名

4.分为如下的三种情况:

情况1:对象::非静态方法

情况 2:类:静态方法

情况3:类:非静态方法

5.要求:

要求接口中的抽象方法的形参列表和返回值类型与方法引用的方法的形参列表和返回值类型相同!(针对情况1和情况2)

当函数式接口方法的第一个参数是需要引用方法的调用者,并且第二个参数是需要引用方法的参数(或无参数时)Classname::MethodName(针对情况3)

6.使用建议:

如果给函数式接口提供实例,恰好满足方法引用的使用情景,大家可以考虑使用方法引用给函数式接口提供实例。如果不熟悉方法引用,可以使用lambda 表达式

7.使用举类:
@Test
public void test4() {

    Consumer<String> con= s-> System.out.println(s);
    con.accept("北京欢迎你!");
    System.out.println("****************");
   PrintStream ps= System.out;
    //方法引用1:对象::非静态方法名
    Consumer<String> con2=ps::println;
    con2.accept("北京欢迎你2!");
}
@Test
public void test5(){
    Function<Double,Long> fun1 =d->Math.round(d);
    System.out.println(fun1.apply(14.2));
    System.out.println("****************");
    //方法引用2:类::静态方法名
    Function<Double,Long> fun2=Math::round;
    System.out.println(fun2.apply(14.6));
}
@Test
public void test6(){
    Person per =new Person(20,"tom");
    Function<Person ,String> f1=p->p.getName();
    System.out.println(f1.apply(per));
    System.out.println("****************");
    //方法引用3:类::非静态方法名
    Function<Person ,String> f2=Person::getName;
    System.out.println(f2.apply(per));


}

四:Stream API:

1.Stream API 的理解:

》stream 关注的 是对数据的运算,与CPU打交道,集合关注的是数据的存储,与内存打交道

》java 8提供了一套api,使用这套api可以对内存中的数据进行过滤,排序,映射,归约等操作

2.注意点:

》stream 自己不会存储元素

》stream 不会改变源对象。相反,他们会返回一个持有结果的新stream

》stream 操作是延迟执行的。这意味着他们会等到需要结果的时候才执行

3.stream 的使用流程:

1)stream的实例化

2)一系列的中间操作(过滤,映射....)

3)终止操作

4.使用流程的注意点:

》一个中间操作链,对数据源的数据进行处理

》一旦执行终止操作,就执行中间操作链,并产生结果。之后,不会在被使用

5.stream实例化
@Test
public void test7(){
    //实例化方式一:调用集合的stream()
    List<Employee> employees = EmploeeData.ListEmployees();
    Stream<Employee> stream = employees.stream();
    System.out.println(stream);
    //实例化方式二:调用数组的静态stream()
Integer[] arr= new Integer[]{1,2,3,4,5,6,7,8,9,10};
    Stream<Integer> stream1 = Arrays.stream(arr);
    System.out.println(stream1);
    //实例化方式三:调用类Stream的of()方法
    Stream<Integer> stream2 = Stream.of(arr);
    System.out.println(stream2);
    //实例化方式四:Stream类的迭代器和生成器
    //迭代器,生成十个偶数
    Stream.iterate(0,t->t+2).limit(10).forEach(System.out::println);
    //生成器,生成十个随机数
    Stream.generate(Math::random).limit(10).forEach(System.out::println);

}
6.中间操作和终止操作
    public void test8(){
        //中间操作:
        Stream<Employee> stream = EmploeeData.ListEmployees().stream();
        // filter(P):过滤器:过滤年龄大于30的员工
        stream.filter(e->e.getAge()>30).forEach(System.out::println);
        System.out.println("*****************");
        // limit(int n):显示前几条数据
        EmploeeData.ListEmployees().stream().limit(3).forEach(System.out::println);
        System.out.println("*****************");
        //skip(int n):跳过 前n条数据,显示剩余数据,如果跳过数据大于集合数据,返回空的stream
        EmploeeData.ListEmployees().stream().skip(4).forEach(System.out::println);

        System.out.println("*****************");
        //map(Functional f):返回映射后的stream,并输出
        EmploeeData.ListEmployees().stream().map(e->e.getName()).forEach(System.out::println);
        System.out.println("*****************");
        //sorted():排序
       Arrays.asList(1,2,8,5,-1,23,6).stream().sorted().forEach(System.out::println);
        //sorted(Comparator com):定制排序
        EmploeeData.ListEmployees().stream().sorted((e1,e2)->Double.compare(e1.getSalary(),e2.getSalary())).forEach(System.out::println);
        //终止操作:
        // allMatch():判断是否都符合
        boolean allMatch = EmploeeData.ListEmployees().stream().limit(5).allMatch(e -> e.getAge() > 20);
        System.out.println(allMatch);
        //max():求最大值
        Optional<Integer> max = EmploeeData.ListEmployees().stream().map(e -> e.getAge()).max(Integer::compareTo);
        System.out.println(max);

        //forEeach():迭代.

        Arrays.asList(1,2,8,5,-1,23,6).stream().forEach(System.out::println);

        //reduce():归约
        Integer reduce = Arrays.asList(1, 2, 8, 5, -1, 23, 6).stream().sorted().reduce(0, Integer::sum);
        System.out.println(reduce);

        //collect():收集,把stream结果集转换为list或set
        List<String> collectList = EmploeeData.ListEmployees().stream().map(e -> e.getName()).collect(Collectors.toList());
        Iterator<String> iterator = collectList.iterator();
        while (iterator.hasNext()){
            System.out.println(iterator.next());
        }
        
    }
}

五:Optional

1.理解:为了解决java中的空指针问题而生

Optional<T>类(java.util.Optional)是一个容器类,它可以保存类的值,

代表这个值存在,或者仅仅报错null,表示这个值不存在,原来用null 表示一个值不存在,

现在Optional可以更好的表达这个概念,并且可以避免空指针

2.常用方法:
@Test
public void test9(){
    String str="hello";
    //str=null;
    //1.of(T t):创建value为T类型的Optional类,且t不能为null
    Optional<String> op1 = Optional.of(str);
    //of()和get()搭配使用,获取内部封装的数据
    System.out.println(op1.get());
    System.out.println("******************");
    //2.ofNullable(T t)创建value为T类型的Optional类,且可以为null
    str=null;
    //ofNullable()和orElse()搭配使用,获取内部封装的数据
    Optional<String> op2 = Optional.ofNullable(str);
    //如果Op2的value为null,则str2的值为"beijing"
    String str2 = op2.orElse("beijing");
    System.out.println(str2);

}
3.典型练习:
class Boy{
    private Girl girl;

    public Girl getGirl() {
        return girl;
    }

    public void setGirl(Girl girl) {
        this.girl = girl;
    }

    public Boy(Girl girl) {
        this.girl = girl;
    }

    public Boy() {
    }
}

class Girl{
    private String name;

    public Girl(String name) {
        this.name = name;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}
       // Optional 之前用法
    public String getGirlName(Boy boy){
        if(boy!=null){
            Girl girl = boy.getGirl();
            if(girl!=null){
                return  girl.getName();
            }
            return null;
        }
        return null;

    }

    @Test
    public void test10(){

        String girlName = getGirlName(new Boy());
        System.out.println(girlName);
        System.out.println();
        Boy boy = new Boy(new Girl("陈德容"));
        String girlName1 = getGirlName(boy);
        System.out.println(girlName1);


    }


    // Optional 实现
    public String getGirlName2(Boy boy){
        Optional<Boy> boyoptional = Optional.ofNullable(boy);
        //boy1 一定非空
        Boy boy1 = boyoptional.orElse(new Boy(new Girl("迪丽热巴")));
        Girl girl = boy1.getGirl();
        Optional<Girl> girl1 = Optional.ofNullable(girl);
        //girl2 一定非空
        Girl girl2 = girl1.orElse(new Girl("古力娜扎"));
        String name = girl2.getName();
        return name;


    }

    @Test
    public void test11() {
        Boy boy =new Boy(new Girl("lily"));
        boy=null;
        String name2 = getGirlName2(boy);

        System.out.println(name2);
    }

}


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

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

相关文章

华为机考入门python3--(11)牛客11-数字颠倒

分类&#xff1a;字符串 知识点&#xff1a; int转字符串 str int(num) 对字符串进行逆序 my_str str[::-1] 题目来自【牛客】 def reverse_integer(n): # 将整数转换为字符串 str_n str(n) # 使用[::-1]来反转字符串 reversed_str str_n[::-1] return reversed…

FINN: 使用神经网络对网络流进行指纹识别

文章信息 论文题目&#xff1a;FINN: Fingerprinting Network Flows using Neural Networks 期刊&#xff08;会议&#xff09;&#xff1a;Annual Computer Security Applications Conference 时间&#xff1a;2021 级别&#xff1a;CCF B 文章链接&#xff1a;https://dl.ac…

BioTech - 小分子药物设计与优化 概述

欢迎关注我的CSDN&#xff1a;https://spike.blog.csdn.net/ 本文地址&#xff1a;https://spike.blog.csdn.net/article/details/135998902 小分子药物设计与优化&#xff0c;是利用计算机辅助技术&#xff0c;根据特定的生物学靶点&#xff0c;发现和改进具有治疗作用的小分子…

Codeforces Round 920 (Div. 3)(A~F)

文章目录 ABCDEF A 按题意模拟即可 #include <bits/stdc.h> #define int long long #define rep(i,a,b) for(int i (a); i < (b); i) #define fep(i,a,b) for(int i (a); i > (b); --i) #define pii pair<int, int> #define pll pair<long long, long…

JavaEE作业-实验二

目录 1 实验内容 2 实验要求 3 思路 4 核心代码 5 实验结果 1 实验内容 实现两个整数求和的WEB程序 2 实验要求 ①采用SpringMVC框架实现 ②数据传送到WEB界面采用JSON方式 3 思路 ①创建一个SpringMVC项目&#xff0c;配置好相关的依赖和配置文件。 ②创建一个Con…

Win32 SDK Gui编程系列之--ListView自绘OwnerDraw

ListView自绘OwnerDraw 1.ListView自绘OwnerDraw 正在试错是否使用了列表视图,尽量制作出智能的表格编辑器。本页显示了业主抽签的表格数据(二维数组数据)的显示方法。 显示画面和整个程序如下所示。使用ListView_GetSubItemRect宏的话,就不需要getRect函数了。 当nCol的…

thinkphp获取用户最新的阅读记录,按书籍id去重,返回最新的阅读记录

通过uid查询data_user_zhangjie的记录 去重shuji_id 获取createtime最新的一条数据 //获取用户章节记录public function getUserZhangjieList(){$uid = input(uid);if(empty

Maven构建OSGI+HttpServer应用

Maven构建OSGIHttpServer应用 官网&#xff08;https://eclipse.dev/equinox/server/http_in_equinox.php&#xff09;介绍有两种方式&#xff1a; 一种是基于”org.eclipse.equinox.http”包的轻量级实现&#xff0c;另一种是基于”org.eclipse.equinox.http.jetty”包&#…

jvm体系结构

一、Jvm 的介绍 1、JVM体系结构 2、JVM运行时数据区 3、JVM内存模型 JVM运行时内存 共享内存区 线程内存区 3.1、共享内存区 共享内存区 持久带(方法区 其他) 堆(Old Space Young Space(den S0 S1)) 持久代&#xff1a; JVM用持久带&#xff08;Permanent Space&…

MySQL数据库语句总结

一. 数据定义语言 DDL 数据定义语言&#xff0c;用来定义数据库对象的&#xff08;比如&#xff1a;数据库、表、字段等&#xff09; 1. 数据库操作 &#xff08;1&#xff09;查询所有的数据库 —— show databases; &#xff08;2&#xff09;创建数据库 —— create dat…

【数据结构】二叉树的顺序结构及实现(堆)

1.二叉树的顺序结构 普通的二叉树是不适合用数组来存储的&#xff0c;因为可能会存在大量的空间浪费。而完全二叉树更适合使用顺序结 构存储。现实中我们通常把堆(一种二叉树)使用顺序结构的数组来存储&#xff0c;需要注意的是这里的堆和操作系统 虚拟进程地址空间中的堆是两…

架设游戏服务器租用价格?腾讯云和阿里云价格对比

游戏服务器租用多少钱一年&#xff1f;1个月游戏服务器费用多少&#xff1f;阿里云游戏服务器26元1个月、腾讯云游戏服务器32元&#xff0c;游戏服务器配置从4核16G、4核32G、8核32G、16核64G等配置可选&#xff0c;可以选择轻量应用服务器和云服务器&#xff0c;阿腾云atengyu…

蓝桥杯嵌入式学习记录——LCD的使用

目录 一、前言 二、LCD代码的移植 三、LCD代码的调用 一、前言 前一篇文章已经简单记录了一下cubeMX软件的使用和LED的点亮&#xff0c;今天来记录一下LCD的使用。LCD的驱动代码有很多&#xff0c;但实际上在蓝桥杯的比赛中用起来非常简单&#xff0c;因为赛点会提供LCD的驱…

nginx upstream server主动健康检测模块ngx_http_upstream_check_module 使用和源码分析(中)

目录 6. 源码分析6.1 解析指令分析6.2 待检查的服务器的添加和状态查询6.3 本模块的进程初始化函数6.4 准备执行健康检测任务6.5 执行健康检测任务本篇对ngx_http_upstream_check_module的源码实现进行详细分析。 关于配置和使用部分可以查看上篇:nginx upstream server主动健…

Layui 表格组件 头部工具栏 筛选列 加入全选和全不选的功能

Layui 表格组件 头部工具栏 筛选列 加入全选和全不选的功能 问题 前端使用Layui表格组件展示后台数据&#xff0c;因数据中涉及字段较多&#xff0c;因此加入了组件中固有的控制表格列隐藏显示的功能。奈何客户希望再此基础上&#xff0c;加入“全选”和“全不选”的功能&…

Github 2024-02-06 开源项目日报Top9

根据Github Trendings的统计&#xff0c;今日(2024-02-06统计)共有9个项目上榜。根据开发语言中项目的数量&#xff0c;汇总情况如下&#xff1a; 开发语言项目数量Python项目4TypeScript项目2C项目1Ruby项目1HTML项目1Go项目1Rust项目1C项目1Kotlin项目1 Magic Mask for And…

【golang】24、go get 和 go mod:indrect 与 go mod tidy

文章目录 go get 会执行如下操作&#xff1a; 操作 go.mod 文件&#xff08;add、update、remove&#xff09;下载依赖到 $GOPATH/pkg/mod 中若已安装&#xff0c;则更新该包&#xff0c;到最新版本 试验前置准备&#xff1a;首先删除已下载的依赖&#xff0c;rm -rf $GOPATH…

Linux虚拟文件系统(VFS)

虚拟地址空间通常是与进程密切相关的概念&#xff0c;而不是文件系统。虚拟地址空间是为了提供进程对内存的抽象和隔离而设计的。 文件系统不使用页表&#xff0c;直接使用物理地址。 虚拟文件系统是linux内核的一个核心子系统。、 虚拟文件系统的目的&#xff1a;通过一个抽…

基于CEVA DSP BX2的架构分析(六)-加载和存储单元(二)

6.4 指针修改机制 LS0和LS1都包含指针修改机制。当使用间接或索引寻址模式时&#xff0c;指针的修改可以与地址生成并行执行。在间接寻址模式中&#xff0c;指针包含地址&#xff0c;而在变址寻址模式下&#xff0c;指针包含偏移量&#xff08;有关这些寻址模式的更多详细信息&…

python实现飞书群机器人消息通知

python实现飞书群机器人消息通知&#xff08;消息卡片&#xff09; 直接上代码 """ 飞书群机器人发送通知 """ import time import urllib3 import datetimeurllib3.disable_warnings()class FlybookRobotAlert():def __init__(self):self.web…