JAVA8~17新特性

news2024/11/26 5:44:24

目录

一、前言

二、JAVA8

Lambda表达式

Stream API

创建方式

中间操作

终止操作

Optional类

三、JAVA9

模块机制

JShell交互式编程

 

接口

新增集合工厂方法

四、JAVA10

局部变量类型判断

五、JAVA11

Lambda表达式补充

String方法的补充

全新的HttpClient 使用

六、JAVA12-16

新的switch语法

文本块

新的instanceof语法

空指针异常的改进

记录类型(record)

七、Java 17

密封类型(sealed关键字)

总结


一、前言

springboot3 最低dk17,java8估计要被弃用了

二、JAVA8

Lambda表达式

相当于匿名内部类的简写

public void test() {
    Thread t1 = new Thread(()-> System.out.println("你好"));  //lambda 表达式  
    t1.start();
    }

规范:

        (名称)-> {代码语句,包括返回值}

        和匿名内部类不同,只支持接口,不支持抽象类

        接口有且只有一个抽象方法

        接口上有@FunctionalInterface 标识

自定义接口

@FunctionalInterface
public interface myBy {
    Integer getAdd(Integer a,Integer b);
  }

       

使用

public void test02() {
  myBy  myBy=(a,b)-> a+b;    //实现接口
  System.out.println(myBy.getAdd(1,2));
 }

有现成的实现可以直接代替

private static Integer Add(Integer a, Integer b){ //加法
    return a+b;
  }
  
  public void test02() {
 // myBy  myBy=(a,b)-> a+b; 
   myBy my=(OneTest::Add);    //借用别人的实现方法
  System.out.println(myBy.getAdd(1,2));
  }

线程安全性,(十分局限,不允许对外部数据进行赋值操作)

错误案例

  List<Integer> list=Arrays.asList(1,1,23,23,456,9,9,12,678,23);  
  Integer a=0;  
    list.forEach(i->{
     a+=i; //请注意,这个写法是错误的,lambda表达式为了保证线程安全不允许对外部数据进行赋值操作,当前编译阶段就会报错
   });  
   System.out.println(a);

Stream API

函数式编程

作用:对集合、数组操作

对比Collections(集合操作工具类),Arrays(数组操作工具类) :

Collections和Arrays会改变原来的集合数据;

Stream则不会,它会返回一个新的带有结果的Stream;

不想改变原有数据的情况下操作集合和数组可以使用Stream;

操作集合和数组建议使用这种方式,进一步减少被优化的可能,能少写for就少写一个

创建方式

public void test012()  {
   
  List<Integer> list=Arrays.asList(1,23,456,12,678,23);    
   // 顺序流 按元素顺序返回
  Stream<Integer> stream1 = list.stream();   
   // 并行流 ,同时取数据    
  Stream<Integer> stream2 = list.parallelStream();    
  //数组类型    
  int[] arr =new int[]{1,2,3,4,5};    
  IntStream stream3 = Arrays.stream(arr);    
  Stream<Integer> integerStream = Stream.of(1, 2, 3, 4, 5);
}


//Math.random() 生成 [0,1)的 double数
//生成10个数
Stream.generate(Math::random).limit(10).forEach(System.out::println);

中间操作

数据过滤(filter)

//数据过滤 保留大于10的数据
// 当filter(e->{return true;}) 返回true才保留当前操作数据
List<Integer> list=Arrays.asList(1,23,456,9,12,678,23);
list.stream().filter(e->e>10).forEach(System.out::println); 
//结果 23,456,12,678,23

截取片段(limit)

List<Integer> list=Arrays.asList(1,23,456,9,12,678,23);
//获得前4条数据 结果 1,23,456,9
list.stream().limit(4).forEach(System.out::println);

舍弃片段(skip)(截取片段 相反)

List<Integer> list=Arrays.asList(1,23,456,9,12,678,23);
//丢弃前面4个数据,结果为12,678,23
list.stream().skip(4).forEach(System.out::println);

去重(distinct)

List<Integer> list=Arrays.asList(1,1,23,23,456,9,9,12,678,23);
//去重 根据equals和hashCode, 结果为:1,23,456,9,12,678
 list.stream().distinct().forEach(System.out::println);

映射(map)

自定义操作

map(e->{return "结果"}) 和filter类似, 只是return是自定义的结果

List<String> list=Arrays.asList("aa","bb","cc","dd");
 // 还是操作数据 ,自定义操作数据,用来返回一些特定数据; str.toUpperCase()转化成大写
 // map(e->{return "结果"}) 和filter类似 只是return是自定义的结果
 //结果 AA,BB,CC,DD
 list.stream().map(str->str.toUpperCase()).forEach(System.out::println);

排序(sorted)

List<Integer> list=Arrays.asList(1,1,23,23,456,9,9,12,678,23);

 // 自然排序 ,结果:1,1,9,9,12,23,23,23,456,678
 // 对类对象的排序需要实现 Comparable 接口
 list.stream().sorted().forEach(System.out::println);
 
 //自定义排序,即使是类对象也不用实现Comparable 接口
 //自定义排序结果为:687,456,23,23,23,12,9,9,1,1
  list.stream().sorted((a,b)->{
                       return  Integer.compare(b,a); 
                       })
                 .forEach(System.out::println);

终止操作

匹配与查找

allMatch(lambda) 检查是所有元素满足条件
anyMatch(lambda) 检查是否至少匹配一个元素
noneMatch(lambda) 检查是否没有匹配的元素
findFirst() 返回第一个元素
findAny() 返回当前流中的任意元素
count() 返回流元素的总个数
max(Double::compare) 返回流中最大值
min(Double::compare)返回流中最小值
forEach(lambda) 内部迭代

匹配与查找示例:




// 1、allMatch 验证是否全部元素满足条件
List<Integer> list=Arrays.asList(1,1,23,23,456,9,9,12,678,23);
// 是否全部元素大于 30;返回false,true;当前结果为false
boolean b = list.stream().allMatch(e -> e > 30);
System.out.println(b);

//2、noneMatch 检查全部元素,是否全部不满足条件
// 全部不满足条件为true
List<Integer> list=Arrays.asList(1,1,23,23,456,9,9,12,678,23);
// 判断全部元素是否没有0,结果为true
boolean b1 = list.stream().noneMatch(e -> e == 0);
System.out.println(b1);

//3、findFirst 返回第一个元素
// 当前结果为 1
List<Integer> list=Arrays.asList(1,1,23,23,456,9,9,12,678,23);
Optional<Integer> first = list.stream().findFirst();
System.out.println(first);

// 4、 findAny 随机返回一个元素
List<Integer> list=Arrays.asList(1,1,23,23,456,9,9,12,678,23);
// ?? 有BUG? 每次都是同一个结果
//Collections.shuffle(list); 还是洗牌好用
  Optional<Integer> first = list.stream().findAny();
  System.out.println(first);
  
//5、count 求元素总数
// 结果为 10
List<Integer> list=Arrays.asList(1,1,23,23,456,9,9,12,678,23);
 long count = list.stream().count();
 System.out.println(count);
 
 //5、max最大值 自然排列取右边值
 //最大值
 Optional<Integer> max = list.stream().max(Double::compare);
 //Optional<Integer> max = list.stream().max((a,b)->Double.compare(a,b));
 System.out.println(max.get());

//6、最小值 自然排列取左边值
Optional<Integer> min = list.stream().min(Double::compare);
//Optional<Integer> min = list.stream().min((a,b)->Double.compare(a,b));
System.out.println(min.get());

//7、遍历
 //  list.forEach(System.out::println); 集合自带了遍历
 list.stream().forEach(System.out::println);

归约(reduce)

// 计算结果,返回计算结果
// 0初始值,lambda累加操作 (a是初始值也是下一次结果值当前初始值设置是0,b是索引为i的元素)
//结果为1235
Integer reduce = list.stream().reduce(0, (a, b) -> a + b); 

收集(collect)

把结果转化为list或set等

// 把结果转化为list
List<Integer> list=Arrays.asList(1,1,23,23,456,9,9,12,678,23);
List<Integer> collect = list.stream().filter(e -> e > 10).collect(Collectors.toList());
System.out.println(collect);

//把结果转化为set
List<Integer> list=Arrays.asList(1,1,23,23,456,9,9,12,678,23);
Set<Integer> collect = list.stream().filter(e -> e > 10).collect(Collectors.toSet());
System.out.println(collect);

Optional类

可以预防空指针异常,

有if(a!=null) 时就优先使用这个类;

可以将任何一个类包装进Optional类中

API方法:

//创建
Optional.of(A) // A必须非空,A为空会报错
Optional.empty() //创建一个非空的Optional实例
Optional.ofNullable(A) //A可以为空 ,A为空不会报错; 使用这个

//返回数据
Optional.ofNullable(A).get() 返回包装的A
Optional.ofNullable(A).orElse(B)  当前A不为空就返回A,否则返回B,(A和B需要是同一个类型)
Optional.ofNullable(A).orElseGet() 如果有值则返回,否则返回有接口实现提供的对象
Optional.ofNullable(A).orElseThrow() 如果有值则将其返回,否则抛出由Supplier接口实现提供的异常

示例:

// 如果A为空就返回B
String A=null; 
String a = Optional.ofNullable(A).orElse("A为空"); 
System.out.println(a);


private  static void hello(String str){
    Optional.ofNullable(str) //包装进入Optional,空的也会放入            
    .ifPresent(i->{
         System.out.println(i); //打印            
           });
    }

Optional不太方便,Lambda里面不能执行对外部属性执行赋值操作还是挺多限制的不如使用Objects.isNull(A)

三、JAVA9

模块机制

module-info.java文件

//暴露出去
module module.a {
    exports com.test;
}

// 只暴露给指定的模块
module module.a {
    exports com.test to module.b;
}

//导入module.a 中暴露的内容
module module.b {
    requires module.a;
}

//依赖的传递性
module module.a {
    exports com.test;
    requires transitive java。logging; // 传递到引用的模块
}

//暴露出去,并且开放反射权限
open module module.a {
    exports com.test;
}

JShell交互式编程

 

接口

接口可以存在私有方法(私有方法必须要实现)

新增集合工厂方法

public void test04() {
    Map<String, Integer> map = Map.of("A", 1, "B", 2); //生成只读map    
    List<Integer> list = List.of(1, 2, 3, 4, 5); // 和Arrays.asList(1, 2, 3, 4, 5)一样,生成只读list        
    //list.add(6); 错误 list是只读的    
    System.out.println(map);
  }

四、JAVA10

局部变量类型判断

怎么变成js了,

public void test05() {
    var a="hello,word";  // 只能定义在方法局部变量  
    // var b; 错误,不能定义未赋值的变量    
    System.out.println(a);
  }

五、JAVA11

Lambda表达式补充

内可以定义 var类型变量;

String方法的补充

public void test06() {

   String str=" ";    
   System.out.println(str.isEmpty()); // 判断内容是否为空(有空格也是false)    
   System.out.println(str.isBlank()); //判断外形是否为空(肉眼观察,即使有空格也是true)
   // str.repeat(2) 重复拼接2次成新字符串
   // str.lines()   根据 \n分割
   //str.strip()  去除首位空格
   // str.stripLeading() 去除首部位空格
   // str.stripTrailing() 去除尾部空格
   
 }

全新的HttpClient 使用

public void test07() throws URISyntaxException, IOException, InterruptedException {
        //创建    
        HttpClient client=HttpClient.newHttpClient();    
        //构建请求    
        HttpRequest request = HttpRequest.newBuilder(new URI("https://www.baidu.com")).GET().build();    
        HttpResponse<String> send = client.send(request, HttpResponse.BodyHandlers.ofString()); 
        //发送请求        
        System.out.println(send.body());
}

六、JAVA12-16

新的switch语法

老方式

private static String grade(int score){
        score/=10;        
        String Gl="";       
         switch (score){
            case 10:
            case 9:
                Gl="优秀";                
                break;            
            case 8:
            case 7:
                Gl="良好";                
                break;            
            case 6:
                Gl="及格";                
                break;            
            default:
                 Gl="不及格";        
        }
        return Gl;
}

switch允许有返回值,不写break

为switch表达式

private static String grade2(int score){
    score/=10;    
    return   switch (score){
                case 10,9->"优秀";                
                case 8,7->"良好";                
                case 6->"及格";                
                default->"不及格";    
              };
 }

返回值yield

private static String grade2(int score){
    score/=10;    
    return   switch (score){
                case 10,9->{
                    //可以执行其他逻辑                    
                    System.out.println("优秀");                    
                    yield "优秀";                
                    }
                
                case 8,7->"良好";                
                case 6->"及格";                
                default->"不及格";    
                };
  }

文本块

public void test09()  {
    // 普通字符串
   String str="adbc\nsdawd";    
   System.out.println(str);    
   //文本块    
   String str2=
             """            
             文本块内容:            
             asaiddawjid            
             "sdfsef"fsef            
             mdkaslekf            
             <a herf="fsdf">             
             """;    
             System.out.println(str2);
    }

新的instanceof语法

旧的用法
    a  instanceof  A
    true: a是A的实例或者 ,a是A类的后代
新补充:
    a  instanceof  A b
    为true时候相当于多执行了一步 A  b=(A)a

可以直接转化对应的类型

//旧的写法
@Override
public boolean equals(Object obj) {
   if(obj ==this) return true;   
   if (obj instanceof Student){
       Student test=(Student) obj;    
       return  test.name.equals(this.name);
    }
   return false;
}

//新写法省一行代码
@Override
public boolean equals(Object obj) {
   if(obj ==this) return true;   
   if (obj instanceof Student test){ // ture时候把obj转化成 了(Student)test
    return  test.name.equals(this.name);   
    }
   return false;
   
}

空指针异常的改进

这个特性应该最容易感知出来(笑~)

有空指针异常时候打印的错误信息明确的指出了哪个参数空指针异常

记录类型(record)

在编译时候自动编译出 get、hashcode、equals、toString等方法

支持实现接口,不支持继承(位置已经被占用)

内部不能定义成员变量

//记录类型
public record Account(String user,String pwd) {
    //private String adb; 错误,不能定义成员变量       
    //定义方法    
    public void Add(){
        System.out.println("调用Add");    
        }
}
//使用
public void test010()  {
    Account account1=new Account("123","2334");    
    account1.Add();    
    System.out.println(account1);
}

七、Java 17

密封类型(sealed关键字)

以前final修饰的类不能被继承

sealed 修饰的类可以定点继承,只允许指定的类继承

要求:

1、可以基于普通类、抽象类、接口也可以是继承自其他抽象类的子类或是实现其他接口的类等
2、必须有子类继承,且不能是匿名内部类或者是lambda的形式
3、sealed写在原来final的位置,但是不能和final、non-selaled关键字同时出现,只能选择其一
4、继承的子类必须标记为final、sealed、non-sealed类型

示例:

//A类
public sealed class A permits B { 
    //只允许B继承A (且B需要是final或者sealed 修饰的)    
    public String name;
}

//B类
public non-sealed class B extends A {
    // B为final时候不允许其他类继承    
    // B为sealed 允许指定类继承    
    // B为B是non-sealed ,重新开放继承权限,使其他类可以继承B来间接继承A ,(关键字怎么还带个 - ,难看)
}
//C类
public class C extends B{
}
// 测试
public void test011()  {
    A a=new A();    
    B b=new B();   
    C c=new C();    
    //A是sealed ,B是non-sealed ,c依旧继承了A中name属性    
    c.name="王";    
    System.out.println(c.name);
 }

总结

你还会继续使用java8吗?

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

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

相关文章

前端理解的HTTP缓存(作用、缓存策略、缓存控制机制、应用)

一、HTTP缓存有什么作用&#xff1f; 缓存是为了重复使用而被存储的&#xff0c;可以减少浏览器和服务器之间通信的次数、降低网络延迟、加速页面加载、提高用户体验性等。不但能使网页打开速度更快&#xff0c;还能减少服务器的压力。 二、 浏览器的缓存策略有哪些&#xff1…

关于SpringBoot、Nginx 请求参数包含 [] 特殊符号 返回400状态

问题来源&#xff1a; 使用RESTful风格发送带有特殊符号(如&#xff1a;点、大括号等)的请求&#xff0c;当使用Nginx做地址映射时会返回报"HTTP Status 400-Bad Request"的错误&#xff0c;这个时候我们需要对Nginx的映射方式做一下调整。 Nginx调整完发现跳转后又报…

Day42: 121. 买卖股票的最佳时机,122.买卖股票的最佳时机II

目录 121. 买卖股票的最佳时机 思路 122.买卖股票的最佳时机II 思路 121. 买卖股票的最佳时机 121. 买卖股票的最佳时机 - 力扣&#xff08;LeetCode&#xff09; 思路 1. 确定dp数组及其下标含义 dp[i][0] 表示第i天持有股票所得最多现金 dp[i][1] 表示第i天不持…

爷孙或者更深组件间传值

如图写法即可 父&#xff1a; provide() {return {errorMessage: this.refTable,}},子&#xff1a; inject: [errorMessage],

组合模式:构建树形结构的灵活设计

组合模式是一种结构型设计模式&#xff0c;它允许我们将对象组合成树形结构&#xff0c;以表示“部分-整体”的层次结构。本文将深入探讨组合模式的原理、结构和使用方法&#xff0c;并通过详细的 Java 示例代码来说明。 1. 组合模式的定义 组合模式是一种将对象组合成树形结…

Maven引入Jacoco插件后无法生成jacoco.exec执行文件

目录 jacoco.exec网上常见关于未生成jacoco.exec原因最终解决方案不生效原因解决方案 完整jacoco插件配置 jacoco.exec 执行数据文件&#xff0c;只有生成该文件&#xff0c;才表示引入插件jacoco成功生效 网上常见关于未生成jacoco.exec原因 网上找了一下解决方式基本都是…

windows下使用arp 协议

/ //自动扫描局域网存活主机 本程序是利用arp协议去获取局域网中的存活主机 arp协议概述 地址解析协议&#xff0c;即ARP&#xff08;Address Resolution Protocol&#xff09;&#xff0c;是根据IP地址获取物理地址的一个TCP/IP协议。主机发送信息时将包含目标IP地址的ARP请…

「Paraverse平行云」入选IDC MarketScape中国实时云渲染解决方案

近日&#xff0c;全球领先的IT研究与咨询顾问机构IDC发布了《IDC MarketScape&#xff1a;中国实时云渲染解决方案2023年厂商评估》报告。作为在实时云渲染技术领域具有代表性的技术提供商&#xff0c;「Paraverse平行云」成功入选报告。 IDC报告通过综合考量厂商在产品、市场…

一文搞懂Goroutine之间的通信Channel

文章目录 Channel定义通道初始化通道通道的操作1、发送/接收2、关闭 多返回值模式for range获取通道值 单向通道selectgoroutine、channel案例 道阻且长&#xff0c;行则将至&#xff0c;行而不辍&#xff0c;未来可期&#x1f31f;。人生是一条且漫长且充满荆棘的道路&#xf…

C++函数cincout的基本用法

C的输入输出格式可比C语言的简单得多&#xff0c;输入函数是cin()&#xff0c;输出函数是cout。 首先是cin的基本用法如下 (假设n 5) #include <iostream> using namespace std; int main() {int n;cin>>n;return 0; } 而它的结果则是 cin不仅可以输入int类型…

从单目数据生成3D模型,Meta智能眼镜摄像头校正算法揭秘

众所周知&#xff0c;Meta下一个目标就是AR眼镜&#xff0c;尽管开发AR比VR面临更多复杂的难题&#xff0c;因此可能还要过一段时间才能看到Meta的AR眼镜。目前&#xff0c;该公司已推出了第一代Ray-Ban Stories智能眼镜&#xff0c;特点是搭载的双摄像头不仅可以拍照&#xff…

Verilog基础之十五、锁存器实现

目录 一、前言 二、工程设计 2.1 工程代码 2.2 综合结果 2.3 Latch实现 一、前言 在之前的文章中介绍过寄存器&#xff0c;本节介绍一个类似的逻辑单元&#xff1a;锁存器。在大部分的资料和文章介绍中&#xff0c;都是告诉读者设计中应尽量避免出现锁存器&#xff0c;这主…

从0到1,带你深入了解react fiber

react16之后&#xff0c;react引入了fiber架构&#xff0c;那么它究竟是什么&#xff0c;如何实现的呢&#xff1f;下面就让笔者带你掰扯掰扯&#xff0c;如有错误&#xff0c;欢迎指正 目录 渲染过程 react15 react16 为什么要引入fiber 不可中断原因 fiber详解 是什么…

百度墨斗鱼文库创作中心源码分析

前言 公司解散&#xff0c;待业中&#xff0c;耗时一天研究了一下百度墨斗鱼文库创作中心源码。实现了后台自动完成任务并通知。 下面主要分析一下实现思路和难点 一&#xff0c;实现思路 调用接口查询未回答的题目列表 合并多个tab下的题目 设置黑白名单&#xff0c;这里…

你知道为什么不用XFP光模块了吗?

在光纤通信应用领域中&#xff0c;10G光模块凭借着较低的成本和功耗被广泛应用于学校、企业等应用场景中。XFP和SFP是10G光模块常见的两种封装类型&#xff0c;那为什么现在市场上XFP光模块应用比较少了呢&#xff1f;下面我们来简单分析一下原因。 一、XFP与SFP光模块的概述 …

从小白到大神之路之学习运维第58天--------Firewalld防火墙

第三阶段基础 时 间&#xff1a;2023年7月12日 参加人&#xff1a;全班人员 内 容&#xff1a; Firewalld防火墙 目录 Firewalld防火墙 一、防火墙 1、netfilter和防火墙管理工具 2、防火墙配置模式 3、Firewalld数据流处理的方式 4、firewalld区域类型 1&#x…

【SVN wc.db 删除不掉的问题】

SVN wc.db 删除不掉的问题 方案1&#xff1a;任务管理器 >性能 >打开资源监视器 > CPU >搜索句柄&#xff0c;关闭相关线程&#xff0c;重试删除。若删除explorer.exe导致资源管理器不显示&#xff0c;在任务管理器新建该任务即可“explorer.exe” 方案2&#xff1…

2023-07-12:RocketMQ如何做到消息不丢失?

2023-07-12&#xff1a;RocketMQ如何做到消息不丢失&#xff1f; 答案2023-07-12&#xff1a; RocketMQ通过刷盘机制、消息拉取机制和ACK机制等多种方式来确保消息投递的可靠性&#xff0c;防止消息丢失。 1.刷盘机制 RocketMQ中的消息分为内存消息和磁盘消息&#xff0c;内…

Acwing.858 Prim算法求最小生成树(朴素Prims算法)

题目 给定一个n个点m条边的无向图&#xff0c;图中可能存在重边和自环&#xff0c;边权可能为负数。求最小生成树的树边权重之和&#xff0c;如果最小生成树不存在则输出impossible。 给定一张边带权的无向图G(V,E)&#xff0c;其中V表示图中点的集合&#xff0c;E表示图中边的…

赛效:如何用在线压缩GIF图片

1&#xff1a;在电脑网页上打开并登录快改图&#xff0c;点击左侧菜单栏里的“GIF压缩”。 2&#xff1a;点击页面中间的上传按钮&#xff0c;将电脑本地的GIF文件上传上去。 3&#xff1a;GIF文件上传成功后&#xff0c;设置下方压缩设置&#xff0c;点击右下角“开始压缩”。…