java-必会jdk1.8新特性

news2024/12/23 11:54:11

1:抽象类的变化


前言:
接口里只能做方法定义不能有方法的实现,抽象类的方法不需要继承类必须去实现的一种方式。
定义一个抽象类TestAbstractclass 如下

package com.lm.jdk8.Abstractclass;

/**
 * 抽象类
 */
public abstract class Abstractclass {
    abstract double calculate(int a);

    // 求平方
    double sqrt(int a) {
        return Math.sqrt(a);
    }
}

使用的时候如下

package com.lm.jdk8.Abstractclass;

import org.junit.jupiter.api.Test;

public class TestAbstractclass {
    @Test
    public void test01() {
        Abstractclass abstractclass = new Abstractclass() {
            @Override
            double calculate(int x) {
                return x * x;
            }
        };
        double calculate = abstractclass.calculate(10);
        System.out.println(calculate);
        double sqrt = abstractclass.sqrt(2);
        System.out.println(sqrt);

    }
}

运行如下:
在这里插入图片描述

2:接口中定义方法-jdk1.8之前不支持


在jdk1.8,不仅可以定义接口,还可以在接口中提供默认的实现。这一个小小的改变却让整个抽象设计都随着改变了!

package com.lm.jdk8.interfacePackage;

/**
 * 接口里面定义的方法必须是 default关键字的
 */
public interface interfaceExample {
    double calculate(int x);

    //平方
    default double sqrt(int x) {
        return Math.sqrt(x);
    }

}

使用方式一

package com.lm.jdk8.interfacePackage;

import org.junit.jupiter.api.Test;

public class TestInterfaceExample {
    @Test
    public void test01() {
        InterfaceExample interfaceExample = new InterfaceExample() {
            @Override
            public double calculate(int x) {
                return x + x;
            }
        };
        double calculate = interfaceExample.calculate(4);
        System.out.println(calculate);
        System.out.println(interfaceExample.sqrt(25));
    }
}

高级用法才能体现出他的骚气 如下

 @Test
    public void test02() {
        InterfaceExample interfaceExample = x -> x * x;
        System.out.println(interfaceExample.calculate(4));

    }

3:Lambda 表达式


为什么会有Lambda 表达式的出现 如上的抽象类和接口给了Lambda 表达式的启发 所以你会从各个我们以前的List、Set等等所有接口中看到默认的方法实现。

List<String> list = Arrays.asList("A", "B", "C");
  @Test
    public void test01() {
        Collections.sort(list, new Comparator<String>() {
            @Override
            public int compare(String a, String b) {
                return b.compareTo(a);
            }
        });
        System.out.println(list);

    }

Collections 工具类提供了静态方法 sort 方法,入参是一个 List 集合,和一个 Comparator 比较器,以便对给定的 List 集合进行排序。上面的示例代码创建了一个匿名内部类作为入参,这种类似的操作在我们日常的工作中随处可见
Java 8 中不再推荐这种写法,而是推荐使用 Lambda 表达: 如下


    @Test
    public void Test02() {
        Collections.sort(list, (String a, String b) -> {
            return b.compareTo(a);
        });
    }

以上还可以更加简短的写法 如下

Collections.sort(names, (String a, String b) -> b.compareTo(a));

 @Test
    public void Test03() {
        Collections.sort(list, (String a, String b) -> b.compareTo(a));
        System.out.println(list);
    }

为了追求极致,我们还可以让它再短点

@Test
    public void Test04() {
        list.sort((x,y)->x.compareTo(y));
        System.out.println(list);
    }

其实底层使用了类型推断机制 这样,你连入参的类型都可以省略啦

4:函数式接口出现


可以看到通过Lambda可以开发出同样功能的逻辑但是代码却很简单,那么Jvm是如何进行类型推断,并且找到对应的方法呢?所谓函数式接口(Functional Interface)就是只包含一个抽象方法的声明。针对该接口类型的所有 Lambda 表达式都会与这个抽象方法匹配。
总结:为了保证一个接口明确的被定义为一个函数式接口(Functional Interface),我们需要为该接口添加注解:

在这里插入图片描述
@FunctionalInterface。

 @Test
    public void test01() {
        IConver<String, String> iConver = new IConver<String, String>() {
            @Override
            public String convert(String param) {
                return param;
            }
        };
        System.out.println(iConver);
    }

4:内置的函数式接口


JDK 1.8 API 包含了很多内置的函数式接口。其中就包括我们在老版本中经常见到的 Comparator 和 Runnable,Java 8 为他们都添加了 @FunctionalInterface 注解,以用来支持 Lambda 表达式。
Predicate 断言

 @Test
    public void test01() {
        Predicate<String> s=a->a.length()>0;
        System.out.println(s.test("o"));
        System.out.println(s.negate().test("o"));
        boolean foo0 = s.test("foo");           // true
        boolean foo1 = s.negate().test("foo");  // negate否定相当于!true

        Predicate<Boolean> nonNull = Objects::nonNull;
        Predicate<Boolean> isNull = Objects::isNull;
        System.out.println(nonNull.test(null));
        Predicate<String> isEmpty = String::isEmpty;
        Predicate<String> isNotEmpty = isEmpty.negate();
    }

Functions 函数
Function 函数式接口的作用是,我们可以为其提供一个原料,他给生产一个最终的产品。通过它提供的默认方法,组合,链行处理(compose, andThen):

 @Test
    public void test12() {
        Function<String, Integer> toInteger = Integer::valueOf;                                         //转Integer
        Function<String, String> backToString = toInteger.andThen(String::valueOf);                     //转String
        Function<String, String> afterToStartsWith = backToString.andThen(new Something()::startsWith); //截取第一位
        String apply = afterToStartsWith.apply("123");// "123"
        System.out.println(apply);
    }

Suppliers
Supplier 与 Function 不同,它不接受入参,直接为我们生产一个指定的结果,有点像生产者模式:

   @Test
    public void test13() {
        Supplier<Person> personSupplier0 = Person::new;
        personSupplier0.get();
        Supplier<String> personSupplier1 = Something::test01;
        personSupplier1.get();
        Supplier<String> personSupplier2 = new Something()::test02;
        System.out.println(personSupplier2);
    }

Consumers
Consumer,我们需要提供入参,用来被消费

@Test
    public void test14() {
        // 参照物,方便知道下面的Lamdba表达式写法
        Consumer<Person> greeter01 = new Consumer<Person>() {
            @Override
            public void accept(Person p) {
                System.out.println("Hello, " + p.firstName);
            }
        };
        Consumer<Person> greeter02 = (p) -> System.out.println("Hello, " + p.firstName);
        greeter02.accept(new Person("Luke", "Skywalker"));  //Hello, Luke
        Consumer<Person> greeter03 = new MyConsumer<Person>()::accept;    // 也可以通过定义类和方法的方式去调用,这样才是实际开发的姿势
        greeter03.accept(new Person("Luke", "Skywalker"));  //Hello, Luke
    }

5:Optionals


Optional 它不是一个函数式接口,设计它的目的是为了防止空指针异常(NullPointerException),要知道在 Java 编程中,空指针异常可是臭名昭著的。

@Test
    public void test1() {
        Optional<String> optional = Optional.of("bam");
        optional.isPresent();                  // true
        optional.get();                        // "bam"
        optional.orElse("回调");    // "bam"
        optional.ifPresent((s) -> System.out.println(s.charAt(0)));
        Optional<Person> optionalPerson = Optional.of(new Person());
        optionalPerson.ifPresent(s -> System.out.println(s.firstName));
    }

6:Stream 流


简单来说,我们可以使用 java.util.Stream 对一个包含一个或多个元素的集合做各种操作。这些操作可能是 中间操作 亦或是 终端操作。 终端操作会返回一个结果,而中间操作会返回一个 Stream 流。
初始化数据

   List<String> list = new ArrayList<>();

    StreamTest() {
        list.add("ddd2");
        list.add("aaa2");
        list.add("bbb1");
        list.add("aaa1");
        list.add("bbb3");
        list.add("ccc");
        list.add("bbb2");
        list.add("ddd1");
    }
    

Filter 过滤
Filter 的入参是一个 Predicate, 上面已经说到,Predicate 是一个断言的中间操作,它能够帮我们筛选出我们需要的集合元素。

  @Test
    public void test17() {
        list.stream().filter((s) -> s.startsWith("a")).forEach(System.out::println);
        System.out.println(list);
    }

Sorted 排序

@Test
public void test18() {
	stringCollection
			.stream()
			.sorted()
			.filter((s) -> s.startsWith("a"))
			.forEach(System.out::println);
}

对象属性排序

tCjpoolSecurityReportList = tCjpoolSecurityReportList.stream().sorted(Comparator.comparing(TCjpoolSecurityReport::getPubdate).reversed()).collect(Collectors.toList());

过滤指定属性

 public static String convertO32Market(String secuMarket) {
        if (StringUtils.isNotEmpty(secuMarket)) {
            List<O32SecuMarketEnum> filters = Arrays.stream(values()).filter((item) -> {
                return StringUtils.equals(secuMarket, item.getIssMktCode());
            }).collect(Collectors.toList());
            return CollectionUtils.isNotEmpty(filters) ? filters.get(0).getO32MktCode() : secuMarket;
        } else {
            return null;
        }
    }

7:Parallel-Streams 并行流


流可以是顺序的,也可以是并行的。顺序流上的操作在单个线程上执行,而并行流上的操作在多个线程上并发执行。

下面的示例演示了使用并行流来提高性能是多么的容易。亲测提升了1倍性能!
顺序流处理 比较慢

@Test
    public void test01() {
        int max = 1000000;
        List<String> values = new ArrayList<>(max);
        for (int i = 0; i < max; i++) {
            UUID uuid = UUID.randomUUID();
            values.add(uuid.toString());
        }
        // 纳秒
        long t0 = System.nanoTime();
        long count = values.stream().sorted().count();
        System.out.println(count);
        long t1 = System.nanoTime();
        long millis = TimeUnit.NANOSECONDS.toMillis(t1 - t0);
        System.out.println(String.format("顺序流排序耗时: %d ms", millis));

    }

并行流处理 嘎嘎快

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

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

相关文章

通信工程学习:什么是PNF物理网络功能

PNF:物理网络功能 PNF(Physical Network Function)即物理网络功能,是指支持网络功能的物理设备。以下是关于PNF的详细解释: 一、定义与特点 定义: PNF是网络设备厂商(如Cisco、华为、H3C等)通过专用硬件实体提供软件功能的设备。这些设备直接在物理服务器上运…

java:异常处理

背景 Java中的异常体系基于几个关键的概念和类&#xff0c;主要包括Throwable类、Exception类&#xff08;及其子类&#xff09;和Error类。 异常分类 1. Throwable 类 Throwable 是所有错误与异常的超类。它有两个直接子类&#xff1a;Error 和 Exception。 2. Error 类 …

【OpenAI o1思维链CoT必看论文】谷歌“思维链提示“让AI更懂人类推理

原创 超 超的闲思世界 AI的推理能力正迎来一场重大突破。谷歌大脑团队最新开发的"思维链提示"方法&#xff0c;让大型语言模型在复杂推理任务上展现出惊人的进步。这项创新技术无需对模型进行额外训练&#xff0c;却能显著提升AI的推理能力&#xff0c;让机器的思…

python命令行怎么换行

在命令行中“>>>”是python的输入提示符&#xff0c;按回车键则表示输入结束。那么如何在命令行中换行呢&#xff1f; 换行方法&#xff1a;\ 如&#xff1a; >>> print aaa; \ ... print bbb; \ ... print ccc 注意“&#xff1b;”的使用。python本身语句…

excel单元格增加可选下拉列表

excel单元格增加可选下拉列表 下拉设置&#xff1a;数据–数据验证-选择序列-填写来源&#xff08;来源数据用英文逗号分隔&#xff09;&#xff08;是,否&#xff09;- 区域应用&#xff1a;选定区域-数据验证-是-确认

2024年第十届信息学与商业工程国际会议(ICIBE 2024)将在泰国曼谷召开!

2024年第十届信息学与商业工程国际会议 (ICIBE 2024) 将于2024年12月20日-22日在泰国曼谷举办。ICIBE 2024由泰国兰实大学主办&#xff0c;中国澳门大学和菲律宾马普亚大学提供技术支持。本次会议为来自世界各地的专业人士、科学家、工程师、教育工作者、学生和研究人员提供了一…

tauri程序加载本地图片或者文件在前端页面展示

要想在前端页面中展示本地文件或者文件夹&#xff0c;需要使用convertfilesrc这个api&#xff0c;可以非常方便的展示内容&#xff0c;官方文档&#xff1a;tauri | Tauri Apps convertFileSrc甚至位于invoke之前&#xff0c;但我却一直没有注意到它&#xff0c;一方面是因为&…

街头摊贩检测系统源码分享

街头摊贩检测检测系统源码分享 [一条龙教学YOLOV8标注好的数据集一键训练_70全套改进创新点发刊_Web前端展示] 1.研究背景与意义 项目参考AAAI Association for the Advancement of Artificial Intelligence 项目来源AACV Association for the Advancement of Computer Vis…

磷酸化多肽及其修饰方法

【知识与技术分享~~~】 磷酸化多肽主要指肽链中的Ser、Tyr和Thr残基的侧链羟基被修饰成酸式磷酸酯多肽&#xff0c;有L构象和D构象之分&#xff0c;其结构如下&#xff1a; 楚肽生物提供 在固相多肽合成SPPS&#xff08;Solid-PhasePeptide Synthesis&#xff09;采用的是Fmoc-…

Day100 代码随想录打卡|动态规划篇--- 01背包问题(一维数组版)

题目&#xff08;卡玛网T46&#xff09;&#xff1a; 小明是一位科学家&#xff0c;他需要参加一场重要的国际科学大会&#xff0c;以展示自己的最新研究成果。他需要带一些研究材料&#xff0c;但是他的行李箱空间有限。这些研究材料包括实验设备、文献资料和实验样本等等&am…

2024外研社综合能力大赛第一场真题

网上找滴~自用 审核不过&#xff0c;备考指南发知乎了&#xff1a;https://zhuanlan.zhihu.com/p/730698685

基于GIKT深度知识追踪模型的习题推荐系统源代码+数据库+使用说明,后端采用flask,前端采用vue

基于GIKT深度知识追踪模型的习题推荐系统 目录结构 Flask-BackEnd flask后端 app 后端主体文件 alg 深度学习模块 data 数据集data_process.py 数据预处理gikt.py GIKT模型pebg.py PEBG模型params.py 一些参数train.py 仅模型训练train_test.py 模型训练和测试-五折交叉验证t…

C++ 语言课程笔记

C 语言课程笔记 C语言程序设计第四版——谭浩强著&#xff0c;此书中的代码题大部分已经在本文中展示&#xff0c;以及南开大学 C 语言上机题库 100 题的作答&#xff0c;如果有作答不正确的地方或者可优化的地方&#xff0c;欢迎指正&#xff0c;谢谢&#xff01; 001 屏幕输出…

一招搞定苹果安卓跨系统传输,文件大小再也不是问题

在当今多元化的科技市场中&#xff0c;众多手机品牌竞相推出各自的产品&#xff0c;每个品牌都力图打造独特的用户体验和生态系统。然而&#xff0c;这种品牌之间的多样性也带来了一定的挑战&#xff0c;尤其是在不同品牌体系之间互联互通性方面。由于每个品牌都有自己的操作系…

VMware虚拟机Centos操作系统——配置docker,运行本地打包的镜像,进入conda环境(vmware,docker新手小白)

1.docker-centos运行sudo yum install -y yum-utils报错 遇到问题 解决&#xff1a; 进入/etc/yum.repos.d目录下找到 CentOS-Base.repo&#xff0c;执行下面两个命令&#xff1a; cp CentOS-Base.repo CentOS-Base.repo.backupvi CentOS-Base.repo 进入后改成&#x…

前缀和(4)_除自身以外数组的乘积

个人主页&#xff1a;C忠实粉丝 欢迎 点赞&#x1f44d; 收藏✨ 留言✉ 加关注&#x1f493;本文由 C忠实粉丝 原创 前缀和(4)_除自身以外数组的乘积 收录于专栏【经典算法练习】 本专栏旨在分享学习算法的一点学习笔记&#xff0c;欢迎大家在评论区交流讨论&#x1f48c; 目录…

央国企董事会管理方案,数字化助力会议、制度、信披、投资全过程全方位管理

董事会建设是中国特色现代企业制度的重要内容。近日&#xff0c;国务院国资委召开中央企业董事会建设工作推进会&#xff1a;到明年年底&#xff0c;中央企业集团和二级子企业层面董事会建设要取得重要实质性进展&#xff0c;董事会制度更加健全、运行更加规范&#xff0c;作用…

如何进行光伏项目卫星踏勘?

一、卫星地图选址 1. 数据获取 卫星踏勘的第一步是获取高分辨率的卫星图像。利用卫星遥感技术&#xff0c;可以获取项目候选区域的地形地貌、植被覆盖等详细信息。这些数据通过专业的遥感图像处理软件进行分析和解译&#xff0c;提取出对光伏电站建设有重要影响的关键因素&am…

【Git使用】向Gitee/Github上传代码时配置gitignore忽略文件

概述&#xff1a; 在进行项目开发时&#xff0c;尤其是使用Git进行版本控制时&#xff0c;我们经常会遇到一些不需要上传到代码仓库的文件&#xff0c;比如编译生成的文件、临时文件、日志文件等。这时候&#xff0c;我们就需要使用.gitignore文件来忽略这些文件。本文将介绍如…

单点登录sso部署

文章目录 同域下的单点登录原理不同域下的单点登录原理 第三方 OAuth2 授权登录支持第三方登录 本地用keycloak实现1、生成证书2、编写docker-compose.yml文件3、创建持久化数据目录4、接下来启动docker-compose5、访问keycloak 单点登录英文全称Single Sign On&#xff0c;简称…