java8 新特性

1、lambda表达式

Lambda 是一个 匿名函数,我们可以把 Lambda 表达式理解为是 一段可以传递的代码(将代码像数据一样进行传递)。使用它可以写出更简洁、更灵活的代码。

(1)语法

Lambda 表达式:在Java 8 语言中引入的一种新的语法元素和操作符。这个操作符为 “->” , 该操作符被称为 Lambda操作符或 箭头操作符。它将 Lambda 分为两个部分:

左侧:指定了 Lambda 表达式需要的参数列表

右侧:指定了 Lambda 体,是抽象方法的实现逻辑,也即Lambda 表达式要执行的功能。

语法格式一 : 无参,无返回值

Rannable r1 = () -> {System.out.println("Hello Lanbda !");}

语法格式二: :Lambda 需要一个参数,但是没有返回值。

Cousumer<String> con = (String str) -> {System.out.println("str");}

语法格式三 : 数据类型可以省略 ,因为可由编译器推断得出,称为“类型推断”

Cousumer<String> con = (str) -> {System.out.println("str");}

语法格式四: :Lambda 若只需要一个参数时, 参数的小括号可以省略

Cousumer<String> con = str -> {System.out.println("str");}

语法格式五: :Lambda 需要两个或以上的参数,多条执行语句,并且可以有返回值

Comparator<Integer> com = (x,y) -> { System.out.println("实现函数式接口方法"); return Integer.compare(x,y); }

语法格式六 :当Lambda 体只有一条语句时,return与大括号若有,都可以省略

Comparator<Integer> com = (x,y) -> Integer.compare(x,y);

(2)类型推断

Lambda表达式中无需指定类型,程序依然可以编译,这是因为 javac 根据程序的上下文,在后台推断出了参数的类型。Lambda 表达式的类型依赖于上下文环境,是由编译器推断出来的。这就是所谓的“类型推断”。

(3)应用示例
       // 1.创建线程new Thread(() -> {// method run,do something}, "threadName").start();// 2.匿名类JButton show = new JButton("show");show.addActionListener(e -> {// method actionPerformed()});// 3.forEach迭代List features = Arrays.asList("Lambdas", "Default Method", "Stream API", "Date and Time API");features.forEach(System.out::println);// 4.map 和reduceList<Integer> costBeforeTax = Arrays.asList(100, 200, 300, 400, 500, 600);costBeforeTax.stream().map(e -> e + 0.12 * e).forEach(System.out::print);double bill = costBeforeTax.stream().map(e -> e + 0.12 * e).reduce((sum, cost) -> sum + cost).get();System.out.println(bill);// 5.过滤 filter 收集 collectList<String> strs = Arrays.asList("abc", "defg", "hi", "jkmln");List<String> filtered = strs.stream().filter(e -> e.length() > 2).collect(Collectors.toList());// 6.去重List<Integer> nums = Arrays.asList(1 ,2, 3, 1, 4, 5, 2, 6, 8, 7, 6);nums = nums.stream().distinct().collect(Collectors.toList());// 7.计算最大值、最小值、平均值、总和List<Integer> primes = Arrays.asList(2, 3, 5, 7, 11, 13, 17, 19, 23, 29);IntSummaryStatistics stats = primes.stream().mapToInt(e -> e).summaryStatistics();System.out.println("最大值:" +  stats.getMax());System.out.println("最小值:" +  stats.getMin());System.out.println("平均值:" +  stats.getAverage());System.out.println("总和:" +  stats.getSum());System.out.println("计数:" +  stats.getCount());
(4)限制

lambda表达式有个限制,只能引用final和final局部变量,也就是说不能再lambda表达式内部修改定义再域外的变量。否则编译报错:

2、函数式(Functional)接口

只包含一个抽象方法的接口,称为 函数式接口。

Lambda表达式就是一个函数式接口的实例。匿名实现类表示的现在都可以用Lambda表达式来写。

java内置四大核心函数式接口:

3、方法引用与构造器引用

 当要传递给Lambda体的操作,已经有实现的方法了,可以使用方法引用!

 方法引用可以看做是Lambda表达式深层次的表达。换句话说,方法引用就是Lambda表达式,也就是函数式接口的一个实例,通过方法的名字来指向一个方法,可以认为是Lambda表达式的一个语法糖。

 要求:实现接口的抽象方法的参数列表和返回值类型,必须与方法引用的方法的参数列表和返回值类型保持一致!

 格式:使用操作符 “::” 将类(或对象)与方法名分隔开来。如下三种主要使用情况:

对象::实例方法名

类::静态方法名

类::实例方法

// 方法引用 ClassName::methodName 
如: Comparator<Integer> com = (x,y) -> Integer.compare(x,y); 
等同于: Comparator<Integer> com = Integer::compare; // 构造器引用 ClassName::new 
如: Function<Integer, MyClass> fun = (n) -> new MyClass(n); 
等同于: Function<Integer, MyClass> fun = MyClass::new; //数组引用 type[] :: new 
如: Function<Integer, Integer[]) fun = (n) -> new Integer[n]; 
等同于: Function<Integer, Integer[]) fun = Integer::new;

4、Stream API

Stream 和 Collection 集合的区别:Collection 是一种静态的内存数据结构,而 Stream 是有关计算的。前者是主要面向内存,存储在内存中,后者主要是面向 CPU,通过 CPU 实现计算。

①Stream 自己不会存储元素。

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

③Stream 操作是延迟执行的。这意味着他们会等到需要结果的时候才执行。

Stream操作的三个步骤:

创建Stream -> 中间操作 -> 终止操作(终端操作)

(1)创建Stream

// 方式1:通过集合 
//Java8 中的 Collection 接口被扩展,提供了两个获取流的方法: 
default Stream<E> stream() : 返回一个顺序流 
default Stream<E> parallelStream() : 返回一个并行流 
例: 
List<Integer> list = Arrays.asList(1, 2, 3, 4, 5); 
Stream<Integer> integerStream = list.stream(); // 方式2:通过数组 
// Java8 中的 Arrays 的静态方法 stream() 可以获取数组流: 
static <T> Stream<T> stream(T[] array): 返回一个流 
重载形式,能够处理对应基本类型的数组: 
public static IntStream stream(int[] array) 
public static LongStream stream(long[] array) 
public static DoubleStream stream(double[] array) 
例: IntStream stream = Arrays.stream(new int[]{1, 2, 3, 4, 5}); // 方式3:通过Stream的of() 
public static<T> Stream<T> of(T... values) // 接收任意可变参数,返回一个流 
例: Stream<String> stringStream = Stream.of("AA", "BB", "CC"); // 方式4: 创建无限流 
>迭代 public static<T> Stream<T> iterate(final T seed, final UnaryOperator<T> f) >
生成 public static<T> Stream<T> generate(Supplier<T> s) 
例: 
// 迭代 
Stream<Integer> stream = Stream.iterate(0, x -> x + 2); stream.limit(10).forEach(System.out::println); 
// 生成 
Stream<Double> stream1 = Stream.generate(Math::random); stream1.limit(10).forEach(System.out::println);

(2)Stream的中间操作

(2.1)筛选与切片

Person p1 = new Person("tom", 11); 
Person p2 = new Person("jerry", 8); 
Person p3 = new Person("marry", 5); 
Person p4 = new Person("john", 14); 
ArrayList<Person> list = new ArrayList<>(); 
list.add(p1); 
list.add(p2); 
list.add(p3); 
list.add(p4); 
// 过滤 
List<Person> collect = list.stream() .filter(p -> p.getAge() > 10).collect(Collectors.toList()); 
// 去重 
Person p5 = new Person("john", 14); 
collect = list.stream() .distinct() .collect(Collectors.toList()); 
// 截断 
collect = list.stream() .limit(2) .collect(Collectors.toList()); 
// 跳过元素 
collect = list.stream() .skip(2) .collect(Collectors.toList());

(2.2)映射

List<String> nameList = list.stream() 
.map(Person::getName) 
.collect(Collectors.toList()); // map()和flatMap类似于集合的add()和addAll(),后者会展开元素

(2.3)排序

// 自定义比较 
List<Person> sortedList = list.stream() .sorted((e1, e2) -> e1.getAge()-e2.getAge()) .collect(Collectors.toList()); 
// 数值的比较方法 
sortedList = list.stream() .sorted((e1, e2) -> Integer.compare(e1.getAge(), e2.getAge())) .collect(Collectors.toList()); 
// Comparator的静态比较方法 
sortedList = list.stream() .sorted(Comparator.comparingInt(Person::getAge)) .collect(Collectors.toList());

(3)Stream的终止操作

(3.1)匹配与查找

boolean allMatch = list.stream().allMatch(e -> e.getAge() > 10); 
Optional<Person> first = list.stream().findFirst(); 
list.stream().filter(e -> e.getAge() > 10).count(); 
Optional<Person> max = list.stream() .filter(e -> e.getAge() > 10) .max(Comparator.comparingInt(Person::getAge)); 
list.stream().filter(e -> e.getAge() > 10).forEach(System.out::println);

(3.2)归约

Optional<Integer> reduce = list.stream() .map(Person::getAge) .reduce((e1, e2) -> e1 + e2);

(3.3)收集

(4)Collectors

5、Optional类

Optional<T> 类(java.util.Optional) 是一个容器类,它可以保存类型T的值,代表这个值存在。或者仅仅保存null,表示这个值不存在。原来用 null 表示一个值不存在,现在 Optional 可以更好的表达这个概念。并且可以避免空指针异常。

Optional提供很多有用的方法,这样我们就不用显式进行空值检测。

创建Optional 类对象的方法:

 Optional.of(T t) : 创建一个 Optional 实例,t必须非空;

 Optional.empty() : 创建一个空的 Optional 实例

 Optional.ofNullable(T t) :t可以为null

判断Optional 容器中是否包含对象:

 boolean isPresent() : 判断是否包含对象

 void ifPresent(Consumer<? super T> consumer) :如果有值,就执行Consumer接口的实现代码,并且该值会作为参数传给它。

获取Optional 容器的对象:

 T get(): 如果调用对象包含值,返回该值,否则抛异常

 T orElse(T other) :如果有值则将其返回,否则返回指定的other对象。

 T orElseGet(Supplier<? extends T> other) : :如果有值则将其返回,否则返回由Supplier接口实现提供的对象。

 T orElseThrow(Supplier<? extends X> exceptionSupplier) : :如果有值则将其返

回,否则抛出由Supplier接口实现提供的异常。

//使用Optional类的getGirlName(): 
public String getGirlName2(Boy boy){ Optional boyOptional = Optional.ofNullable(boy); //此时的boy1一定非空 Boy boy1 = boyOptional.orElse(new Boy(new Girl("迪丽热巴"))); Girl girl = boy1.getGirl(); Optional girlOptional = Optional.ofNullable(girl); //girl1一定非空 Girl girl1 = girlOptional.orElse(new Girl("古力娜扎"));return girl1.getName(); 
}

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

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

相关文章

STM32WB55开发(1)----套件概述

STM32WB55开发----1.套件概述 所用器件视频教学样品申请优势支持协议系统控制和生态系统访问功能示意图系统框图跳线设置开发板原理图 所用器件 所使用的器件是我们自行设计的开发板&#xff0c;该开发板是基于 STM32WB55 系列微控制器所构建。STM32WBXX_VFQFPN68 不仅是一款评…

【MyBatis篇】MyBatis框架基础知识笔记

目录 ORM思想&#xff08;对象关系映射思想&#xff09; 初识MyBatis 什么是MyBatis呢&#xff1f; JDBC VS MyBatis代码 获取数据库连接对比 对表格查询操作&#xff1a; JDBC弊端 MyBatis&#xff0c;JDBC对比 MyBatis进一步介绍以及本质分析 JDBC编程的劣势&…

VectorDraw Developer Framework 10.1004 Crack

VectorDraw 开发人员框架 (VDF) 是一个图形引擎库&#xff0c;开发人员可以使用它来可视化其应用程序。通过提供的功能&#xff0c;我们的客户可以轻松创建、编辑、管理、导出、导入和打印 2D 和 3D 绘图 - 图形文件。VDF 使用的强大格式称为 VDML&#xff08;以及与 VDML 相同…

ssprompt:一个LLM Prompt分发管理工具

阅读顺序 &#x1f31f;前言&#x1f514;ssprompt介绍命令介绍Metafile介绍版本依赖规则 &#x1f30a; PromptHubGitHub Token &#x1f680; Quick Install系统依赖pip安装Linux, macOS, Windows (WSL)Windows (Powershell) &#x1f6a9; Roadmap&#x1f30f; 项目交流讨论…

12.redis 持久化

redis 持久化 redis 持久化redis持久化策略RDB > Redis DataBase 定期备份rdb 文件处理rdb 优缺点 AOF > Append Only File 实时备份AOF 工作流程AOF 缓冲区刷新策略AOF 重写机制AOF 重写流程 混合持久化持久化流程总结 redis 持久化 redis 是一个内存数据库&#xff0c…

【大数据模型】让chatgpt为开发增速(开发专用提示词)

汝之观览&#xff0c;吾之幸也&#xff01;本文主要聊聊怎样才能更好的使用提示词&#xff0c;给开发提速&#xff0c;大大缩减我们的开发时间&#xff0c;比如在开发中使用生成表结构脚本的提示词&#xff0c;生成代码的提示词等等。 一、准备 本文主要根据Claude进行演示&am…

【产线故障】线上接口请求过慢如何排查?

文章目录 前言一、内存使用过高导致CPU满载案例代码分析思路 二、出现了类似死循环导致cpu负载案例代码分析思路 三、死锁案例代码分析思路 前言 首先线上接口变慢&#xff0c;原因可能有很多&#xff0c;有可能是网络&#xff0c;有可能是慢 SQL&#xff0c;有可能是服务本身…

【Linux】- 一文秒懂shell编程

shell编程 1.1 Shell 是什么1.2 Shell 脚本的执行方式1.3 编写第一个 Shell 脚本2.1 Shell 的变量2.2 shell 变量的定义2.3 设置环境变量3.1 位置参数变量3.2 预定义变量4.1 运算符4.2 条件判断5.1 流程控制5.2 case 语句5.3 for 循环5.4 while 循环5.5 read基本语法6.1函数6.2…

Nginx 本地部署服务

nginx 部署服务 一、下载二、解压三、文件替换四、浏览器中输入五、离线部署瓦片服务 一、下载 可以到官网下载&#xff0c;官方网址&#xff1a;https://nginx.org/也可以用我发的包 二、解压 三、文件替换 解压打开后文件&#xff0c;双击 nginx.exe 浏览器输入 localhost…

springboot之一:配置文件(内外部配置优先顺序+properties、xml、yaml基础语法+profile动态切换配置、激活方式)

配置的概念&#xff1a; Spring Boot是基于约定的&#xff0c;所以很多配置都有默认值&#xff0c;但如果想使用自己的配置替换默认配置的话&#xff0c;就可以使用application.properties或者application.yml(application.yaml)进行配置。 注意配置文件的命名必须是applicat…

【LeetCode每日一题合集】2023.8.28-2023.9.3(到家的最少跳跃次数)

文章目录 57. 插入区间823. 带因子的二叉树解法——递推 1654. 到家的最少跳跃次数(BFS&#xff0c;&#x1f6b9;最远距离上界的证明)1761. 一个图中连通三元组的最小度数2240. 买钢笔和铅笔的方案数解法1——完全背包解法2——枚举买了几支钢笔&#xff08;推荐解法&#xff…

LGFormer:LOCAL TO GLOBAL TRANSFORMER FOR VIDEO BASED 3D HUMAN POSE ESTIMATION

基于视频的三维人体姿态估计的局部到全局Transformer 作者&#xff1a;马海峰 *&#xff0c;陆克 * †&#xff0c;薛健 *&#xff0c;牛泽海 *&#xff0c;高鹏程† * 中国科学院大学工程学院&#xff0c;北京100049 鹏程实验室&#xff0c;深圳518055 来源&#xff1a;202…

这可能是最全面的Python入门手册了!

无论是学习任何一门语言&#xff0c;基础知识一定要扎实&#xff0c;基础功非常的重要&#xff0c;找到一个合适的学习方法和资料会让你少走很多弯路&#xff0c; 你的进步速度也会快很多&#xff0c;无论我们学习的目的是什么&#xff0c;不得不说Python真的是一门值得付出时间…

代码泄漏无感知?代码安全审计构筑企业核心资产安全防线

目录 一个不眠之夜 源代码托管&#xff1a;最容易被从内部攻破的堡垒 审计事件&#xff0c;构建源代码安全防护的“最后一道防线” 源代码托管审计事件三要素 源代码托管审计事件的价值 极狐GitLab 审计事件功能 极狐GitLab 审计事件功能特点 极狐GitLab 审计事件功能使…

Support for password authentication was removed on August 13, 2021 解决方案

打开你的github&#xff0c;Setting 点击Developer settings。 点击generate new token 按照需要选择scope 生成token&#xff0c;以后复制下来。 给git设置token样式的remote url git remote set-url origin https://你的tokengithub.com/你的git用户名/仓库名称.git然后就可…

Docker 搭建Redis 集群之路

前言 搞技术就是动手&#xff0c;动手再动手&#xff0c;实践出真知&#xff0c;毕竟最终是要解决问题的呢&#xff0c;废话不多讲&#xff0c;开搞&#xff0c;主要是为了记录一下&#xff0c;毕竟过程还是有点艰辛呢需求&#xff08;target&#xff09; Windows 电脑 装一个…

python 笔记(1)——基础和常用部分

目录 1、print 输出不换行 2、格式化输出字符串 3、浮点数的处理 4、进制转换和ASCII与字符间的转换 5、随机数 6、字符串截取和内置方法 6-1&#xff09;字符串截取 6-2&#xff09;字符串内置方法 7、元组、列表&#xff0c;及其遍历方式 7-1&#xff09;列表常用内…

为什么5G 要分离 CU 和DU?(4G分离RRU 和BBU)

在 Blog 一文中&#xff0c;5G--BBU RRU 如何演化到 CU DU&#xff1f;_5g rru_qq_38480311的博客-CSDN博客 解释了4G的RRU BBU 以及 5G CU DU AAU&#xff0c;主要是讲了它们分别是什么。但是没有讲清楚 为什么&#xff0c;此篇主要回答why。 4G 为什么分离基站为 RRU 和 BBU…

Windows下搜索文件内容的关键字用什么命令

Windows下搜索文件内容的关键字用什么命令 findstr /s /n /i "keyword" file_path其中&#xff0c;/s 表示递归检索子文件夹&#xff0c;/n 表示显示搜索结果所在行号&#xff0c;/i 表示忽略大小写&#xff0c;“keyword” 是要搜索的关键字&#xff0c;file_path 是…

【LeetCode-中等题】17. 电话号码的字母组合

文章目录 题目方法一&#xff1a;递归回溯 题目 方法一&#xff1a;递归回溯 参考讲解&#xff1a;还得用回溯算法&#xff01;| LeetCode&#xff1a;17.电话号码的字母组合 首先可以画出树图&#xff1a; 先将数字对应的字符集合 加入到一个map集合 这里需要一个index来控…