JDK8的新特性

目录

  • 接口的默认方法和静态方法 
  • Lambda表达式
  • 1、匿名内部类
  • 2、函数式接口(@FunctionalInterface)
  • 2.1 无参函数式接口匿名内部类方式-->Lambda表达式方式 
  • 2.2 有参函数式接口匿名内部类方式-->Lambda表达式方式  
  •  3、Lambda实战
  •  3.1 循环遍历
  •  3.2 集合排序
  •  3.3 创建线程
  • 方法引用
  • Optional 
  • Stream流
  •  1、遍历、遍历筛选(foreach/filter)
  •  2、聚合函数、排序(max/min/count/sorted)
  •  3、映射(map)
  •  4、规约(reduce)
  •  5、收集、转换(collect) 
  • 新的日期API 

接口的默认方法和静态方法 

JDK8允许在接口中定义默认方法和静态方法(带有方法体) 

public interface interfaceChange {//普通方法---public abstractvoid normalMethod();//默认方法---defaultdefault void defaultMethod(){System.out.println("我是jdk1.8中接口中的默认方法,带有方法体的!");}//静态方法---staticstatic void staticMethod(){System.out.println("我是jdk1.8中接口中的静态方法,带有方法体的!");}
}
public class InterfaceChangeImpl implements interfaceChange{//必须重写普通方法@Overridepublic void normalMethod() {System.out.println("我是重写接口的add方法!");}public static void main(String[] args) {InterfaceChangeImpl i = new InterfaceChangeImpl();//调用重写方法i.normalMethod();//调用默认方法i.defaultMethod();//调用静态方法interfaceChange.staticMethod();}
}

Lambda表达式

1、匿名内部类

当我们想使用接口中的方法,但是不想创建子类去重写再调用,我们就可以使用匿名内部类来实现快速简洁调用接口中的方法

//如果接口中只有一个方法
public static void main(String[] args) {new interfaceChange() {@Overridepublic void normalMethod() {System.out.println("通过匿名内部类实现的方法1!");}}.normalMethod();
}
//如果接口中有多个方法
public static void main(String[] args) {interfaceChange i = new interfaceChange() {@Overridepublic void normalMethod() {System.out.println("通过匿名内部类实现的方法1!");}@Overridepublic void normalMethod2() {System.out.println("通过匿名内部类实现的方法2!");}};i.normalMethod();i.normalMethod2();}

 2、函数式接口(@FunctionalInterface)

2.1 无参函数式接口匿名内部类方式-->Lambda表达式方式 

//无参
@FunctionalInterface//声明为函数式接口---只能有一个普通方法
public interface UserMapper {//普通方法void get();
}
//无参匿名内部类方式
new UserMapper() {@Overridepublic void get() {System.out.println("无参匿名内部类方式");}
}.get();
//无参Lambda表达式方式     ------方法体如果只有一条语句,可省略{ }
UserMapper u = () -> System.out.println("无参Lambda表达式方式");
u.get();
//更精简表达式
((UserMapper)()-> System.out.println("无参Lambda表达式方式")).get();

2.2 有参函数式接口匿名内部类方式-->Lambda表达式方式  

//有参
@FunctionalInterface
public interface StudentMapper {public void select(String name,Integer age);
}
//有参匿名内部类方式
System.out.println(new StudentMapper() {@Overridepublic String select(String name, Integer age) {return name + "" + age;}}.select("Mike",20)
);//有参Lambda表达式方式
StudentMapper s = (x,y)-> x + "" + y;    ----只有一条语句且有返回值,可省略return和{ }
System.out.println(s.select("Mike", 3));
//更精简表达式
System.out.println( ((StudentMapper) (x, y) -> x + "" + y).select("Mike", 40));

  3、Lambda实战

   3.1 循环遍历

List<Integer> list = Arrays.asList(20,54,10,
//实战---循环遍历
//Lambda方式
list.forEach(s-> System.out.println(s));
//stream流方式
list.stream().forEach(System.out::println);

    3.2 集合排序

//实战---排序
//lambda方式
list.sort((x,y)->x-y);//正序
System.out.println("list = " + list);
list.sort((x,y)->y-x);//逆序
System.out.println("list = " + list);
//stream流方式
list.stream().sorted(Integer::compareTo).collect(Collectors.toList());//正序
list.stream().sorted(Comparator.comparing(Integer::intValue).reversed()).collect(Collectors.toList());//逆序

     3.3 创建线程

//实战---线程
new Thread(()->{ System.out.println("线程开始!"); }).start();

方法引用

静态方法引用

        类名::静态方法名

对象方法引用

        类名::实例方法名

实例方法引用

        对象实例::方法名

构造函数引用

        类名::new

Optional 

创建Optional容器:

public static void main(String[] args) {//创建一个空的Optional容器Optional<Object> empty = Optional.empty();//创建一个非空的Optional容器(参数必须有值)Student s = new Student("MIke",20,"大学");Optional<Student> op = Optional.of(s);//创建一个可接受null参数的Optional(主用)Optional<Student> s1 = Optional.ofNullable(s);
}

 判断容器中是否为空:

//判断容器中是否为空
boolean present = op.isPresent(); 空->true,非空->false//判断容器中是否为空,并且可通过Lambda表达式进行下一步操作
op1.ifPresent(p->p.setName("李四"));
Optional.ofNullable(s).ifPresent(p->p.setAge(0)); //(主用)
System.out.println(s);

获取容器中的对象:

//获取容器中的对象
Student s1 = null;
Student s2 = new Student("Amy",55,"硕士");
//get()   如果为空报异常
Student student = Optional.ofNullable(s1).get();
//get()   正常则返回对象
Student student2 = Optional.ofNullable(s2).get();
//orElse()  如果为空则返回其他的对象,像三目运算符(s1==null?s2:s1)
Student student3 = Optional.ofNullable(s1).orElse(new Student("Jghn",44,"博士"));
//orElseThrow()    如果为空则抛出异常
Student student4 = Optional.ofNullable(s1).orElseThrow(()->new RuntimeException("对象为空!!"));

Stream流

 1、遍历、遍历筛选(foreach/filter)

List<String> list = new ArrayList<>();
list.add("张三");
list.add("李四");
list.add("王五");
//普通遍历
list.stream().forEach(System.out::println);
//筛选遍历
list.stream().filter(s -> "张三".equals(s)||"李四".equals(s)).forEach(System.out::println);

List<Student> list1 = new ArrayList<>();
list1.add(new Student("Mike",20,"大学"));
list1.add(new Student("Amy",21,"大学"));
list1.add(new Student("Jhon",22,"高中"));
list1.add(new Student("Lihua",10,"初中"));
//普通遍历
list1.stream().forEach(System.out::println);
//筛选遍历并输出新的集合
List<Student> collect = list1.stream().filter(s -> s.getAge() <= 20).collect(Collectors.toList());
System.out.println("年龄小于等于20的学生:collect = " + collect);
//遍历筛选符合条件的元素并且指定属性返回
List<String> collect1 = list1.stream().filter(s -> "大学".equals(s.getGrade())).map(Student::getName).collect(Collectors.toList());
System.out.println("学历为大学的学生:collect1 = " + collect1);

2、聚合函数、排序(max/min/count/sorted)

max/min: 

List<String> list2 = Arrays.asList("1","30","55","78","9999","55");
List<Integer> list3 = Arrays.asList(10,30,55,78,9999);
//取字符串最大长度
Optional<String> max = list2.stream().max(Comparator.comparing(String::length));
System.out.println("max = " + max.get());
//取Integer最大值
Optional<Integer> max1 = list3.stream().max((Integer::compareTo));
System.out.println("max1 = " + max1.get());
//取对象属性中年龄最大的
Optional<Student> max2 = list1.stream().max(Comparator.comparing(Student::getAge));
System.out.println("max2 = " + max2.get());---------最小值类推即可

count: 

//计数
long count = list2.stream().filter(s -> "55".equals(s)).count();
System.out.println("属性为“55”的元素有:count = " + count);
long count1 = list1.stream().filter(s -> "大学".equals(s.getGrade())).count();
System.out.println("大学生有:count = " + count1);

sorted: 

//方式一:
//正序
list.stream().sorted(Integer::compareTo).collect(Collectors.toList());//逆序
list.stream().sorted(Comparator.comparing(Integer::intValue).reversed()).collect(Collectors.toList());//方式二:
//正序
list.stream().sorted((x,y)->x-y).forEach(System.out::println);
list1.stream().sorted((x,y)->x.getAge()-y.getAge()).forEach(System.out::println);
//逆序
list.stream().sorted((x,y)->y-x).forEach(System.out::println);
list1.stream().sorted((x,y)->y.getAge()-x.getAge()).forEach(System.out::println);

 3、映射(map)

List<String> list4 = Arrays.asList("abcd", "bcdd", "defde", "fTr");
//String类型集合将小写转大写
list4.stream().map(String::toUpperCase).forEach(System.out::println);
//Integer类型集合每个元素+5
List<Integer> integerList = list3.stream().map(s -> s += 5).collect(Collectors.toList());
System.out.println("每个元素+5之后的新integerList = " + integerList);
//实体集合将每个学生的年龄-5
List<Student> collect = list1.stream().map(s -> {Integer age = s.getAge();s.setAge(age -= 5);return s;
}).collect(Collectors.toList());
System.out.println("年龄全部-5的新集合是:collect = " + collect);

4、规约(reduce)

//Integer集合求和
Optional<Integer> reduce = list3.stream().reduce(Integer::sum);
//Optional<Integer> reduce = list3.stream().reduce((x, y) -> x + y);
System.out.println("和为:reduce = " + reduce.get());
//Integer集合求积
Optional<Integer> reduce1 = list3.stream().reduce((x, y) -> x * y);
System.out.println("积为:reduce1 = " + reduce1.get());
//String集合求组合
Optional<String> reduce2 = list4.stream().reduce((x, y) -> x + y);
System.out.println("组合为:reduce2 = " + reduce2.get());
//实体集合求年龄总和
Optional<Integer> reduce3 = list1.stream().map(Student::getAge).reduce(Integer::sum);
System.out.println("年龄总和为:reduce3 = " + reduce3.get());

5、收集、转换(collect) 

从字面上去理解,就是把一个流收集起来,最终可以是收集成一个值也可以收集成一个新的集合。

collect主要依赖java.util.stream.Collectors类内置的静态方法。

收集成List:Collectors.toList()

收集成Set:Collectors.toSet()   (注:对象收集要去重的话需要重写hashCode和toString

收集成Map:Collectors.toMap()   

List<Integer> list5 = Arrays.asList(1, 6, 3, 4, 6, 7, 9, 6, 20, 7);//将偶数收集起来
List<Integer> collect = list5.stream().filter(x -> x % 2 == 0).collect(Collectors.toList());
System.out.println("collect = " + collect);//将奇数收集起来并且不重复
Set<Integer> collect1 = list5.stream().filter(x -> x % 2 != 0).collect(Collectors.toSet());
System.out.println("collect1 = " + collect1);//将实体集合中年龄大于等于20的收集起来--List
List<Student> collect2 = list1.stream().filter(s -> s.getAge() >= 20).collect(Collectors.toList());
System.out.println("collect2 = " + collect2);//将实体集合中年龄小于等于20的收集起来--Map
Map<?, Student> collect3 = list1.stream().filter(s -> s.getAge() < 20).collect(Collectors.toMap(Student::getName, s -> s));
System.out.println("collect3 = " + collect3);

 

新的日期API 

 ​​​​

//1、设计不合理并且是可变的,线程不安全
Date date = new Date(2020,7,26);//2、时间格式化并且线程不安全
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
System.out.println(simpleDateFormat.format(date));

 

 

Date、Calendar、SimpleDateFormat都是线程不安全的。而JDK8加入了LocalDate、LocalTime、LocalDateTime、DateTimeFormatter通过加了Final修饰实现了不可变,解决线程安全问题。

//新的LocalDate
LocalDate localDate = LocalDate.now();
LocalDate localDate1 = LocalDate.of(2024,7,26);//新的LocalTime
LocalTime localTime = LocalTime.now();
LocalTime localTime1 = LocalTime.of(16,41,50);//新的LocalDateTime
LocalDateTime localDateTime = LocalDateTime.now();
LocalDateTime localDateTime1 = LocalDateTime.of(2024,7,26,16,41,50);//新的DateTimeFormatter
DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ISO_LOCAL_DATE_TIME;
System.out.println(dateTimeFormatter.format(localDateTime));
DateTimeFormatter dateTimeFormatter1 = DateTimeFormatter.ofPattern("yyyy/MM/dd HH-mm-ss");
System.out.println(dateTimeFormatter1.format(localDateTime));

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

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

相关文章

黑马头条Day12-项目部署_持续集成

一、今日内容介绍 1. 什么是持续集成 持续集成&#xff08;Continuous integration&#xff0c;简称CI&#xff09;&#xff0c;指的是频繁地&#xff08;一天多次&#xff09;将代码集成到主干。 持续集成的组成要素&#xff1a; 一个自动构建过程&#xff0c;从检出代码、…

Golang处理Word文档模板实现标签填充|表格插入|图标绘制和插入

本教程主要实现【Golang处理Word文档模板实现标签填充|表格插入|图标绘制和插入】。 本文源码&#xff1a;https://gitee.com/songfayuan/go-zero-demo 教程源码分支&#xff1a;master 分支&#xff08;_examples/word-template/fill-word-template.go&#xff09; Golang处理…

Java-Swing开发-001组件

文章目录 Top-level containerJFrame容器对话框相关 JComponent组件面板相关文本相关菜单相关工具栏按钮下拉框进度条树形组件 Top-level container 1.JFrame 2.JDialog JFrame容器 //设置APP图标 this.setIconImage(new ImageIcon(getClass().getResource("/button/i…

论文解读(10)-图神经网络

加油&#xff0c;继续看论文。 这次学图神经网络&#xff0c;这个概念经常在其他论文里出现&#xff0c;所以我想先学习一下这方面的知识。 参考&#xff1a; 【图神经网络综述】一文道尽GNN原理、框架和应用-CSDN博客 【图神经网络】10分钟掌握图神经网络及其经典模型_图神经…

某“新一线城市“前端面试,纯纯被恶心到了

一.起因 在boss上刷到的一个小小厂&#xff0c;收大四全年实习生(web前端)&#xff0c;因为离家乡比较近&#xff0c;而且双非一本的学历以及入坑的时间没有太长(前端部分不到一年)&#xff0c;想去那里看看形势&#xff0c;要求是笔试面试&#xff0c;当场给是否录用结果&…

AgentBench: Evaluating LLMs As Agents

AgentBench: Evaluating LLMs As Agents Github&#xff1a; https://github.com/THUDM/AgentBench 榜单&#xff1a;https://llmbench.ai/agent/data demos&#xff1a;https://llmbench.ai/agent/demo 备注&#xff1a;该论文介绍为AgentBench v0.2版本 一、介绍 现如今&am…

三行代码高搞定nestjs静态图片映射方案

方案一 nestjs/serve-static 库映射 上代码 npm i nestjs/serve-staticimport { ServeStaticModule } from nestjs/serve-static; import { join } from path; const staticPath join(__dirname, .., /public/);Module({imports: [ServeStaticModule.forRoot({rootPath: sta…

用Python代码调用GPT-SoVITS

GPT-SoVITS 项目地址&#xff1a;https://github.com/RVC-Boss/GPT-SoVITS import os import requests from PySide6.QtCore import QThread from PySide6.QtWidgets import QWidget, QApplication from design import Ui_Form import subprocess import sounddevice as sd im…

JAVA基础 - 泛型

目录 一. 简介 二. 集合泛型 三. 自定义泛型 四. 自定义泛型类和普通类的区别 一. 简介 泛型是 Java 语言中一种强大的特性&#xff0c;它允许在定义类、接口和方法时使用类型参数&#xff0c;从而增加了代码的类型安全性和复用性。 类型安全性&#xff1a; 使用泛型可以…

day07 项目启动以及git

spring框架 spring 负责整合各种框架&#xff0c;把new对象的部分交给spring去做&#xff0c;对象new不出来&#xff0c;项目就启动不起来&#xff0c;这样可以有效保证所需要的对象都在容器中存在&#xff0c;后续的部分都可以顺利执行控制反转&#xff1a;业务对象创建依赖资…

“八股文”在实际工作中是助力、阻力还是空谈?

一&#xff1a;浅谈 关于“八股文”在程序员面试中的重要性和实际工作中的作用&#xff0c;确实是一个引发广泛讨论的话题。以下是我对这个问题的看法&#xff1a; 1. “八股文”的定义与特征 “八股文”通常指的是面试中常见的标准化问答或经典理论知识&#xff0c;例如…

Apollo:源码分析之cyber/mainboard启动入口介绍-my write, test ok

软件结构图 cyber入口 cyber的入口在"cyber/mainboard"目录中: ├── mainboard.cc // 主函数 ├── module_argument.cc // 模块输入参数 ├── module_argument.h ├── module_controller.cc // 模块加载,卸载 └── module_controller.…

关于Docker Engine AuthZ 插件授权绕过漏洞 (CVE-2024-41110)

一、漏洞概述 漏洞名称&#xff1a;Docker Engine AuthZ 插件授权绕过漏洞 &#xff08;CVE-2024-41110&#xff09; 漏洞等级&#xff1a;高危 漏洞描述&#xff1a;DockerEngine是Docker的核心组件&#xff0c;是一 个开源的容器引擎&#xff0c;负责构建、运行和管理容器…

【Vue】权限控制

权限管理 分类&#xff1a; 页面权限功能(按钮)权限接口权限 vue3-element-admin 的实现方案 一般我们在业务中将 路由可以分为两种&#xff0c;constantRoutes 和 asyncRoutes。 constantRoutes&#xff1a; 代表那些不需要动态判断权限的路由&#xff0c;如登录页、404(或…

【echarts】 柱状图,最后带“竖线”

具体&#xff1a; https://echarts.zhangmuchen.top/#/detail?cid28ea6-0601-e9f5-9cc29-c022b758 let data [{value: 0,name: 数据格式一},{value: 55,name: 数据格式二},{value: 66,name: 数据格式三},{value: 75,name: 数据格式四},{value: 20,name: 数据格式五}];getAr…

盘点.软件测试模型

软件开发模型   软件开发模型(Software Development Model)是指软件开发全部过程、活动和任务的结构框架。软件开发包括需求、设计、编码和测试等阶段&#xff0c;有时也包括维护阶段。 软件开发模型能清晰、直观地表达软件开发全过程&#xff0c;明确规定了要完成的主要活动…

C++类与对象-六大成员函数

默认成员函数就是用户没有显式实现&#xff0c;编译器会⾃动⽣成的成员函数称为默认成员函数。⼀个空类编译器会默认⽣成8个默认成员函数。本文只介绍其中6个&#xff0c;C11增加两个函数见后续博客。 目录 一、构造函数 1.1 概念 1.2 特性 1.3 使用举例 1.4 初始化列表 1…

如何通过前端表格控件实现自动化报表?

背景 最近伙伴客户的项目经理遇见一个问题&#xff0c;他们在给甲方做自动化报表工具&#xff0c;项目已经基本做好了&#xff0c;但拿给最终甲方&#xff0c;业务人员不太买账&#xff0c;项目经理为此也是天天抓狂&#xff0c;没有想到合适的应对方案。 现阶段主要面临的问…

docker笔记7-dockerfile

docker笔记7-dockerfile 一、dockerfile介绍二、dockerfile指令三、构建自己的镜像 一、dockerfile介绍 Dockerfile是用来构建Docker镜像的构建文件&#xff0c;是由一系列命令和参数构成的脚本。 以下是常用的 Dockerfile 关键字的完整列表和说明&#xff1a; 二、docker…

【计算机毕业设计】838装修公司CRM系统

&#x1f64a;作者简介&#xff1a;拥有多年开发工作经验&#xff0c;分享技术代码帮助学生学习&#xff0c;独立完成自己的项目或者毕业设计。 代码可以私聊博主获取。&#x1f339;赠送计算机毕业设计600个选题excel文件&#xff0c;帮助大学选题。赠送开题报告模板&#xff…