当前位置: 首页 > news >正文

JDK8新增特性(值得收藏)

1.Lamdba表达式

就相当于要使用接口Lock就不需要再创建一个类去实现接口了,直接用Lambda表达式省略了在创建的那个类。

Lamdba表达式是什么?

“->”,Lambda操作符或箭 头操作符,它将Lambda表达式分割为两部分。

左边:指Lambda表达式的所有参数

右边:指Lambda 体,即表示Lambda表达式需要执行的功能

public static void main(String[] args) {//使用匿名函数
new Thread(new Runnable(){
@Override
public void run(){
System.out.println("我是没有使用Lambda表达式:不简洁");
}
}).start();//使用Lambda表达式
new Thread(
()->System.out.println("我是使用Lambda表达式:简洁、灵活")
).start();
}

六种语法格式:
1. 语法格式一:无参数、无返回值,只需要一个Lambda体
//接口
public interface Lock {public abstract void lockUp(String str);
}//主方法使用接口
public static void main(String[] args) {
Lock lock = ()-> System.out.println("Lambda表达式:简洁、灵活,优雅永不过时");lock.lockUp();
}

2. 语法格式二:lambda有一个参数、无返回值
public interface Lock {public abstract void lockUp(String str);
}//有一个参数,无返回值Lock lock = (s) -> System.out.println(s+"上锁");
lock.lockUp("张三");

3. 语法格式三:Lambda只有一个参数时,可以省略()
Lock lock = s -> System.out.println(s+"上锁");
lock.lockUp("张三");

4. 语法格式四:Lambda有两个参数时,并且有返回值
//接口
public interface Lock {
public abstract String lockUp(String str,String str2); }// 有两个参数并且有返回值
Lock lock = (s1,s2) ->{System.out.println("门被上锁");return "上锁";};lock.lockUp("张三",2);

5.语法格式五:当Lambda体只有一条语句的时候,return和{}可以省略掉

现在连return和{}都不要了

Lock lock1 = (s1,s2) ->"拉屎";
lock1.lockUp("张三",2);

6.语法格式六:类型推断
//写上类型
Lock lock2 = (s)-> System.out.println(s+"上锁");
lock2.lockUp("张三");//可以不写类型
Lock lock = (s)-> System.out.println(s+"上锁");
lock.lockUp("张三");

2. forEach+Lambda

1. 使用forEach和Lambda循环list集合

本来是应该这样子使用循环的

//使用forEach和Lambda循环list集合
List<String> list = new ArrayList<String>();list.add("A");list.add("B");list.add("C");for (String s:list){System.out.println(s);}

使用Lambda表达式的循环

//使用forEach和Lambda循环list集合
list.forEach(s->System.out.println(s));

Lambda版:

这里的s就代表add的括号里面的参数

       List<UserVo> list = new ArrayList<UserVo>();list.add(new UserVo());list.add(new UserVo());list.add(new UserVo());list.forEach(s->System.out.println(s.getUserName()));

2. 使用forEach和Lambda循环Map集合

这里的k就代表第一个参数,v就代表第二个参数

Map<String, UserVo> map = new HashMap<String, UserVo>();
map.put("A", new UserVo());
map.put("B", new UserVo());
map.put("C", new UserVo());
map.forEach((k,v)->System.out.println(k+"==="+v.getUserName()));

3.函数式接口:

因为接口中可能会有很多方法,我们如果用Lambda是默认的接口中的那个方法,所以函数式接口就是只包含一个抽象方法的接口。使用@FunctionalInterface 注解。符合函数式接口的才能够使用表达式。

接口中有两个方法就会报错

4. 方法引用和构造器引用

4.1方法引用

因为接口如果想实现方法需要借别人的方法体,::后面的就是别人的方法,也就是你想用的方法

接着简化Lambda表达式

使用操作符“::”将方法名和(类或者对象)分割开来。

有下列三种情况:

对象::实例方法

类::实例方法

类::静态方法

对象::实例方法

Lock lock = System.out::println; 使用了方法引用,表示将 System.out 对象的 println 方法作为 lockUp 的实现。

当调用lock.lockUp(""); 时,它实际上调用的是 System.out.println(" ");。

@FunctionalInterface
public interface Lock {
public abstract void lockUp(String str); //上锁
}Lock lock = System.out::println;
lock.lockUp("测试。。。");
例题:

像这一题使用的类::静态方法因为Runnable里面的run( )没有方法体,借用的Hello类里面的a方法,然后用调用run方法时就调用的是Hello里面的a方法了,因为有两个方法a

我们要选择适合自己的,第二个a有参数所以pass

4.2构造器引用

格式:ClassName :: new

代码分析:

  • Lock 是一个函数式接口,定义了一个抽象方法 lockUp,其接受一个 String参数并返回一个 String。
  • 当我们调用方法时需要返回一个String,所以Lambda省略了return和{}之后是这样的
  • 所以根据构造器的格式就是String::new

@FunctionalInterface
public interface Lock {
public abstract String lockUp(String str); //上锁
}//非构造器引用
Lock lock1 = (s) -> new String(s);//构造器引用
Lock lock2 = String::new;

5. Stream API

Java8中两个最为重要特性:第一个的是Lambda表达式,另一个是Stream API。

StreamAPI帮助我们更好地对数据进行集合操作,它本质就是 对数据的操作进行流水线式处理,也可以理解为一个更加高级的迭代器,主要作用是遍其中每一个元 素。简而言之,StreamAP提供了一种高效且易于使用的处理数据方式。

Stream特点:

1、Stream自己不会存储数据。

2、Stream不会改变源对象。相反,它们会返回一个持有结果的新Stream对象

3、Stream操作时延迟执行的。这就意味着它们等到有结果时候才会执行。

3. Stream操作的三个步骤?

1、创建Stream:一个数据源(例如:set 、list),获取一个流

2、中间操作:一个中间操作连接,对数据源的数据进行处理

3、终止操作:一个终止操作,执行中间操作连,产生结果。

4. Stream创建可以通过三种方式创建。

1. 通过 java.util.Collection.stream() 方法用集合创建流

2. 使用 java.util.Arrays.stream(T[] array) 方法用数组创建流

3. 使用 Stream 的静态方法: of()、iterate()、generate()

//1.通过 `java.util.Collection.stream()` 方法用集合创建流
List<String> list = Arrays.asList("d","a", "b", "c");
Stream<String> streamList = list.stream();
System.out.println("###############顺序流##############");
streamList.forEach(System.out::print);
System.out.println();
System.out.println("###############并行流##############");
// 创建一个并行流
//效率高,线程不安全
Stream<String> parallelStream = list.parallelStream();
parallelStream.forEach(System.out::print);
System.out.println();
//2.使用`java.util.Arrays.stream(T[] array)`方法用数组创建流
int[] array={1,3,5,6,8};
IntStream streamint = Arrays.stream(array);
streamint.forEach(System.out::print);
System.out.println();
//3.使用`Stream`的静态方法:`of()、iterate()、generate()
Stream<Integer> stream = Stream.of(1, 2, 3, 4, 5, 6);
stream.forEach(System.out::print);
System.out.println();
Stream<Integer> stream2 = Stream.iterate(0, (x) -> x + 3).limit(4);
stream2.forEach(System.out::print);
System.out.println();
Stream<Double> stream3 = Stream.generate(Math::random).limit(3);
stream3.forEach(System.out::print);
System.out.println();

5.中间操作:

用这个代码举例子

public static void main(String[] args) {
ArrayList<String> list = new ArrayList<>();
Collections.addAll(list, "张无忌", "周芷若", "赵敏", "张强", "张三丰","张无
忌");
}
(1).limit(n) 从list中取出n个元素
list.stream().limit(2).forEach(System.out::println);
(2).skip(n) 从list第n个元素开始,取出所有元素

list.stream().skip(3).forEach(System.out::println);
(3).distinct() 去除重复

list.stream().distinct().forEach(System.out::println);

(4).filter(Predicate<? super T> predicate) 筛选条件

括号中的内容为一个断言型函数式接口,其中的T为当前集合中元素的类型。

断言型函数式接口是指只包含一个抽象方法的接口用于对输入进行测试并返回布尔值。

 List<Person> userList = new ArrayList<>();userList.add(new Person("欧阳雪", 18));userList.add(new Person("Tom", 24));userList.add(new Person("Harley", 22));userList.add(new Person("向天笑", 20));userList.add(new Person("李康", 22));userList.add(new Person("小梅", 20));userList.add(new Person("何雪", 21));

//打印对象要重写toString方法
userList.stream().filter((a) -> a.getAge() > 20).forEach(System.out::println);

(5).map(Function mapper ) 将元素转换成其他形式或提取信息。

// 将 Person 对象转换为其年龄
userList.stream().map(a -> a.getAge()).forEach(System.out::println);
(6).sorted() 对元素进行排序

年龄由小到大, // 使用比较器比较年龄

userList.stream()
.sorted((a, b) -> Integer.compare(a.getAge(), b.getAge()))
.forEach(System.out::println); // 打印排序后的结果 }

终端操作:

1.forEach() 遍历流中每一个元素,会关闭流
list.stream().forEach(System.out::println);

2. findFirst(),findAny() 查找操作

查找第一个、任何一个,返回的类型为Optional可以用get方法获取字符串。

String first = list.stream().findFirst().get();
System.out.println(first);

3. allMatch,anyMatch,noneMatch

allMatch 要求Stream中所有元素都满足条件才返回true

anyMatch, 只要有1个元素满足就返回true

noneMatch 要求所有的元素都不满足条件才返回true

        List<Person> userList = new ArrayList<>();userList.add(new Person("欧阳雪", 18));userList.add(new Person("Tom", 24));userList.add(new Person("Harley", 22));userList.add(new Person("向天笑", 20));userList.add(new Person("李康", 22));userList.add(new Person("小梅", 20));userList.add(new Person("何雪", 21));//每个学生年纪都为18才返回trueboolean flag = userList.stream().allMatch(e -> e.getAge() == 18);
//任意一个学生是18,则返回trueboolean flag1 = userList.stream().anyMatch(e -> e.getAge() == 18);
//学生年纪没有一个是18 ,则返回trueboolean flag2 = userList.stream().noneMatch(e -> e.getAge() == 18);System.out.println("flag:"+flag+"  flag1:"+flag1+"   flag2:"+flag2);

4. reduce:将整个数据流的值规约为一个值

其中count、min、max底层就是使用reduce,也可用于 字符串连接

通过get返回

 // 字符串连接,concat = "ABCD"
String concat = Stream.of("A", "B", "C", "D").reduce("", String::concat);
// 集合累加求和,另一写法reduce(0,Integer::sum)
int sum2=Stream.of(1,2,3,4,5).reduce((t,u)->t+u).get();
//输出最大值,另一写法reduce(Integer::max)
int max1=Stream.of(1,2,3,4,5).reduce((t,u)-> t>=u? t:u).get();

5.min、max`最值操作:返回数据流中最大、最小的值

需要自定义比较器,

//查年纪最大的
Optional<Person> max =
userList.stream().max(Comparator.comparing(Person::getAge));
if (max.isPresent()) {
Person person = max.get();
System.out.println(person);}

6. count : 返回Stream中元素的个数
long count = userList.stream().count();
System.out.println(count);

7. toArray 数组操作:将数据流的元素转换成数组
List<String> list=Arrays.asList("a","b","c","a");
//返回数组
String[] newArr=list.stream().toArray(String[]::new);

8.将Stream转换为list 语法:Stream对象名.collect(Collectors.toList());
List<Student> list = new ArrayList<Student>();
list.add(new Student("张三",18, "男"));
list.add(new Student("李四",17, "男"));
list.add(new Student("王五",19, "女"));
list.add(new Student("马化腾",37, "女"));
list.add(new Student("丁三石",19, "男"));
list.add(new Student("马浮云",31, "女"));
list.add(new Student("军儿",29, "男"));
//将Stream转换为list 语法:Stream对象名.collect(Collectors.toList());
List<Student> list1 = list.stream().
filter(t->t.getSage()>20).
collect(Collectors.toList());

总结:

相关文章:

JDK8新增特性(值得收藏)

1.Lamdba表达式 就相当于要使用接口Lock就不需要再创建一个类去实现接口了&#xff0c;直接用Lambda表达式省略了在创建的那个类。 Lamdba表达式是什么&#xff1f; “->”,Lambda操作符或箭 头操作符&#xff0c;它将Lambda表达式分割为两部分。 左边&#xff1a;指Lam…...

MATLAB系列06:复数数据、字符数据和附加画图类

MATLAB系列06&#xff1a;复数数据、字符数据和附加画图类 6. 复数数据、字符数据和附加画图类6.1 复数数据6.1.1 复变量&#xff08; complex variables&#xff09;6.1.2 带有关系运算符的复数的应用6.1.3 复函数&#xff08; complex function&#xff09;6.1.4 复数数据的作…...

【永磁同步电机(PMSM)】 4. 同步旋转坐标系仿真模型

【永磁同步电机&#xff08;PMSM&#xff09;】 4. 同步旋转坐标系仿真模型 1. Clarke 变换的模型与仿真1.1 Clarke 变换1.2 Clarke 变换的仿真模型 2. Park 变换的模型与仿真2.1 Park 变换2.2 Park 变换的仿真模型 3. Simscape标准库变换模块3.1 abc to Alpha-Beta-Zero 模块3…...

CSAPP Attack Lab

个人感觉非常有意思的一个 Lab&#xff0c;涉及的知识面比较窄&#xff0c;主要关注 缓冲区溢出漏洞 这一个方面&#xff0c;并基于此进行代码攻击&#xff0c;体验一把做黑客的感觉&#xff0c;对应知识点为书中的 3.10 节内容。 这个 Lab 上手便给了我当头一棒&#xff0c;在…...

通信工程学习:什么是NFVI网络功能虚拟化基础设施层

NFVI&#xff1a;网络功能虚拟化基础设施层 NFVI&#xff08;Network Functions Virtualization Infrastructure&#xff09;即网络功能虚拟化基础设施层&#xff0c;是NFV&#xff08;Network Functions Virtualization&#xff0c;网络功能虚拟化&#xff09;架构中的一个重要…...

不在同一局域网怎么远程桌面?非局域网环境下,实现远程桌面访问的5个方法分享!

非局域网环境下&#xff0c;怎么远程桌面&#xff1f;还能做到吗&#xff1f; 在企业管理中&#xff0c;远程桌面访问已成为提高工作效率、实现跨地域协同工作的关键工具。 然而&#xff0c;当被控端与控制端不在同一局域网时&#xff0c;如何实现远程桌面连接成为了许多企业…...

SparkSQL-初识

一、概览 Spark SQL and DataFrames - Spark 3.5.2 Documentation 我们先看下官网的描述&#xff1a; SparkSQL是用于结构化数据处理的Spark模块&#xff0c;与基本的Spark RDD API不同。Spark SQL提供的接口为Spark提供了更多关于正在执行的数据和计算结构的信息。在内部&a…...

Go语言的垃圾回收(GC)机制的迭代和优化历史

Go语言的垃圾回收&#xff08;GC&#xff09;机制自Go语言发布以来经历了多次重要的迭代和优化&#xff0c;以提高性能和减少程序运行时的停顿时间。 以下是一些关键的版本和相应的GC优化&#xff1a; Go版本GC耗时情况主要改进点Go 1.0-1.4可能达到几百毫秒至秒级使用简单的标…...

thinkphp8 从入门到放弃(后面会完善用到哪里写到哪)

thinkphp8 从入门到放弃 引言 thinkphp* 大道至简一、 thinkphp8 安装安装Composerthinkphp 安装命令(tp-项目名称)多应用安装&#xff08;一个项目不会只有一个应用&#xff09;安装完文件目录如下本地部署配置伪静态好了项目可以run 二、架构服务&#xff08;Service&#xf…...

对于电商跨境电商独立站中源代码建站和SaaS建站的区别

电商跨境电商独立站的搭建有多种方式&#xff0c;作为电商企业&#xff0c;搭建完全自主控制的电商独立站&#xff0c;对于电商企业的发展和运营有着至关重要的作用。下面推荐一个使用多年的跨境电商独立站系统源码&#xff0c;做简要介绍&#xff0c;据说前段时间火爆的Pandab…...

使用vite+react+ts+Ant Design开发后台管理项目(二)

前言 本文将引导开发者从零基础开始&#xff0c;运用vite、react、react-router、react-redux、Ant Design、less、tailwindcss、axios等前沿技术栈&#xff0c;构建一个高效、响应式的后台管理系统。通过详细的步骤和实践指导&#xff0c;文章旨在为开发者揭示如何利用这些技术…...

C++之 string(中)

C之 string string类对象的容量操作 resize 将有效字符的个数该成n个&#xff0c;多出的空间用字符c填充 虽然在string里用的不多&#xff0c;但是在vector里面常见 这里有三种情况&#xff1a; 1&#xff09;resize小于当前的size 2)resize大于当前的size,小于capacity …...

双向链表的基本结构及功能实现

1.基本结构: 双向链表是一种链表数据结构&#xff0c;它由一系列节点组成&#xff0c;每个节点包含三个部分&#xff1a; (1).数据域&#xff1a;存储节点的数据 (2).前驱指针:指向前一个节点 (3).后驱指针:指向下一个节点 2.基本特性&#xff1a; 双向链接: 与单向链表…...

stm32定时触发软件中断

这里使用定时器作为延时&#xff0c;单位为秒&#xff0c;使用exti的软件触发方式&#xff0c;配置见代码&#xff0c;在main里进行触发软件中断 代码 #include "stm32f10x.h" #include "stm32f10x_gpio.h" #include "misc.h" #include "…...

blender设置背景图怎么添加?blender云渲染选择

Blender是一款功能强大的3D建模软件&#xff0c;它以流畅的操作体验和直观的用户界面而闻名。使用Blender&#xff0c;你可以轻松地为你的3D模型添加背景图片。 以下是具体的操作步骤&#xff1a; 1、启动Blender&#xff1a;首先&#xff0c;打开Blender软件。访问添加菜单&a…...

MMD模型及动作一键完美导入UE5-Blender方案(三)

1、下载并安装blender_mmd_tools插件 1、下载并安装Blender,Blender,下载Blender3.6,下载太新的版本可能会跟blender_mmd_tools不匹配 2、github下载blender_mmd_tools:https://github.com/UuuNyaa/blender_mmd_tools/ 3、Edit->Preference->Add ons->Install F…...

网络安全自学入门:(超详细)从入门到精通学习路线规划,学完即可就业

很多人上来就说想学习黑客&#xff0c;但是连方向都没搞清楚就开始学习&#xff0c;最终也只是会无疾而终&#xff01;黑客是一个大的概念&#xff0c;里面包含了许多方向&#xff0c;不同的方向需要学习的内容也不一样。 算上从学校开始学习&#xff0c;已经在网安这条路上走…...

如何在O2OA中使用ElementUI组件进行审批流程工作表单设计

本文主要介绍如何在O2OA中进行审批流程表单或者工作流表单设计&#xff0c;O2OA主要采用拖拽可视化开发的方式完成流程表单的设计和配置&#xff0c;不需要过多的代码编写&#xff0c;业务人员可以直接进行修改操作。 在流程表单设计界面&#xff0c;可以在左边的工具栏找到Ele…...

三、LLM应用开发准备工作

LLM应用开发准备工作 开发基础开发工具大模型kxswkey的配置与使用工具推荐结语 开发基础 最好具备一定的Python开发基础&#xff0c;不需要特别深 如果不具备&#xff0c;可以先学习一下基础知识&#xff08;概念&#xff09;&#xff0c;比如Python环境管理、包管理与使用、基…...

机器学习-可解释性机器学习:随机森林与fastshap的可视化模型解析

可解释性机器学习是指使机器学习模型的决策过程透明化&#xff0c;帮助用户理解模型如何得出特定结果。随机森林和 FastSHAP 是常用的工具&#xff0c;以下是对它们的简要解析和可视化方法。 随机森林 1. 概述 随机森林是一种集成学习方法&#xff0c;通过构建多个决策树并结…...

使用Assimp加载glb/gltf文件,然后使用Qt3D来渲染

文章目录 1.代码2.说明2.1.调用2.2.关于贴图 1.代码 ModelLoader.h #ifndef MODELLOADER_H #define MODELLOADER_H#include <QObject> #include <Qt3DRender> #include <QVector3D> #include <QGeometry>#include <assimp/Importer.hpp> #incl…...

vue实现左侧数据拖拽到右侧区域,且左侧数据保留且左侧数据不能互相拖拽改变顺序

一、案例效果 二、案例代码 封装左侧抽屉 DrawerSearch.vue<template><div><mtd-form :model="formDrawerSearch" ref="formCustom" inline><mtd-form-item><mtd-inputtype="text"v-model="formDrawerSearch.ho…...

人工智能与机器学习原理精解【21】

文章目录 SVM求两线段上距离最近的两个点问题描述&#xff1a;距离函数&#xff1a;解法&#xff1a;具体步骤&#xff1a;特别注意&#xff1a;示例代码 SVM思想的介入1. **SVM 的基本思想**超平面&#xff1a; 2. **分类间隔&#xff08;Margin&#xff09;**1. **分类间隔的…...

【MySQL 01】数据库基础

目录 1.数据库是什么 2.基本操作 数据库服务器连接操作 数据库和数据库表的创建 服务器&#xff0c;数据库&#xff0c;表关系 数据逻辑存储 3.MySQL架构 4.SQL分类 5.存储引擎 1.数据库是什么 mysql&&mysqld&#xff1a; mysql&#xff1a;这通常指的是 MySQL …...

C语言字符学习中级使用库解决问题

学习C语言中的字符处理&#xff0c;对于初学者来说&#xff0c;理解字符的基本概念以及如何进行操作是非常重要的。字符处理是指对单个字符或一组字符&#xff08;字符串&#xff09;的操作。为了更好地理解&#xff0c;下面从基础开始介绍&#xff0c;并结合一些常用的函数和示…...

网络管理:网络故障排查指南

在现代IT环境中,网络故障是不可避免的。快速、有效地排查和解决网络故障是确保业务连续性和用户满意度的关键。本文将详细介绍网络故障排查的基本方法和步骤,确保内容通俗易懂,并配以代码示例和必要的图片说明。 一、网络故障排查的基本步骤 确认故障现象 确认用户报告的故…...

Springboot常见问题(bean找不到)

如图错误显示userMapper bean没有找到。 解决方案&#xff1a; mapper包位置有问题&#xff1a;因为SpringBoot默认的包扫描机制会扫描启动类所在的包同级文件和子包下的文件。注解问题&#xff1a; 比如没有加mapper注解 然而无论是UserMapper所在的包位置还是Mapper注解都是…...

架构设计笔记-5-软件工程基础知识

知识要点 按软件过程活动&#xff0c;将软件工具分为软件开发工具、软件维护工具、软件管理和软件支持工具。 软件开发工具&#xff1a;需求分析工具、设计工具、编码与排错工具。 软件维护工具&#xff1a;版本控制工具、文档分析工具、开发信息库工具、逆向工程工具、再工…...

Solidity——抽象合约和接口详解

&#x1f680;本系列文章为个人学习笔记&#xff0c;目的是巩固知识并记录我的学习过程及理解。文笔和排版可能拙劣&#xff0c;望见谅。 Solidity中的抽象合约和接口详解 目录 什么是抽象合约&#xff1f;抽象合约的语法接口&#xff08;Interface&#xff09;的定义接口的语…...

Fyne ( go跨平台GUI )中文文档-入门(一)

本文档注意参考官网(developer.fyne.io/) 编写, 只保留基本用法go代码展示为Go 1.16 及更高版本, ide为goland2021.2 这是一个系列文章&#xff1a; Fyne ( go跨平台GUI )中文文档-入门(一)-CSDN博客 Fyne ( go跨平台GUI )中文文档-Fyne总览(二)-CSDN博客 Fyne ( go跨平台GUI )…...