JAVA8~17新特性

这篇具有很好参考价值的文章主要介绍了JAVA8~17新特性。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

目录

一、前言

二、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交互式编程

JAVA8~17新特性,web后端的学习,java,开发语言

 

接口

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

新增集合工厂方法

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吗?文章来源地址https://www.toymoban.com/news/detail-555748.html

到了这里,关于JAVA8~17新特性的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Java8常用新特性

    目录 简介 1.默认方法 2..Lambda表达式 3.Stream API 4.方法引用 5.Optional类 Java 8是Java编程语言的一个重要版本,引入了许多令人兴奋和强大的新特性。这些特性使得Java程序更加现代化、灵活和高效。让我们一起来探索一些Java 8的常用新特性吧! 首先,Java 8引入了函数式编程的概念

    2024年01月22日
    浏览(39)
  • Java8新特性—方法引用

    前言 Java 8引入了方法引用(method reference)作为一种语言特性,它可以简化代码,使得代码更加易读和易于维护。方法引用可以被视为Lambda表达式的简写形式,可以用来替代Lambda表达式中只调用一个已有方法的情况。总的来说该特性使得Java代码更加简洁和灵活。 使用场景 J

    2024年02月03日
    浏览(38)
  • Java8新特性-流式操作

    在Java8中提供了新特性—流式操作,通过流式操作可以帮助我们对数据更快速的进行一些过滤、排序、去重、最大、最小等等操作并且内置了并行流将流划分成多个线程进行并行执行,提供更高效、快速的执行能力。接下来我们一起看看Java8为我们新增了哪些便捷呢? 目录 什

    2024年02月02日
    浏览(45)
  • Java8新特性整理记录

    方法一:  方法二:   例子:

    2024年02月11日
    浏览(43)
  • Java8的新特性以及使用

    1.   通 过 1 0 个示 例 来 初 步认 识 J a v a 8 中 的 l a m bd a 表达 式   我个 人 对 J a v a   8 发 布 非 常 激动 , 尤 其 是 l a m b d a 表 达式 和 流 AP I 。 越 来 越 多 的 了解 它 们 , 我 能 写 出 更 干 净 的代 码 。 虽然 一 开 始 并 不 是 这 样 。 第一 次 看 到 用 la m b d a 表

    2024年02月07日
    浏览(50)
  • 安装Java8和Java17共存,如何自由切换Java版本?

    官方下载地址:https://www.oracle.com/java/technologies/downloads/ 根据需要选择要下载的Java版本 安装过程省略,有需要的可自行百度 … 找到自己java安装的目录 进入Java jdk的bin目录,如:C:java8jdk1.8.0_331bin,将java.exe改为java8.exe 同样的方式去修改java17的java文件名称 将Java8和Java17的b

    2024年02月09日
    浏览(57)
  • 【Java8新特性--->异步处理】CompletableFuture

    一、引入 假设一个商品详情页需要以下操作: 查询展示商品的基本信息耗时:0.5s 查询展示商品的销售信息耗时:0.7s 查询展示商品的图片信息耗时:1s 查询展示商品销售属性耗时:0.3s 查询展示商品规格属性耗时:1.5s 查询展示商品详情信息耗时:1s 即使每个查询时间耗时不

    2024年02月06日
    浏览(43)
  • Java8新特性-Lambda表达式

    Lambda表达式 Lambda是一个匿名函数, 可以把lambda表达式理解为是一段可以传递的代码,(将代码像数据一样传递) 变化 需求: 求 薪资高于5000的员工信息 Lambda基本语法 在 java8 中引入了一个新的操作符 \\\"-\\\" , 箭头操作符, 箭头操作符 将Lambda表达式拆分为两部分: 左侧: Lambda表达式的参

    2024年02月01日
    浏览(42)
  • Java8新特性—Lambda表达式

    Java 8是Java编程语言的一个版本,于2014年发布。它引入了许多新的特性和改进。 Lambda表达式是Java 8中引入的一个重要的新特性,它提供了一种更加简洁、灵活的方式来编写函数式接口的实现,从而提高了代码的可读性和简洁性。 在本文中,我们将介绍Lambda表达式的基本语法、

    2024年02月03日
    浏览(42)
  • Java8新特性:Optional类(超详解)

    本博主将用CSDN记录软件开发求学之路上亲身所得与所学的心得与知识,有兴趣的小伙伴可以关注博主!也许一个人独行,可以走的很快,但是一群人结伴而行,才能走的更远! 到目前为止,臭名昭著的 空指针异常 是导致Java应用程序失败的最常见原因。以前,为了解决空指

    2023年04月09日
    浏览(43)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包