Java8新特性(Lambda表达式、Stream流、Optional类)等
1. Lambda表达式由来
1 package java8;
2
3 public class EmployeeTest {
4 public static void main(String[] args) {
5
6 Employee employee1 = new EmployeeImpl();
7 employee1.getSalary();
8 System.out.println("****************");
9
10
11 Employee employee2 = new Employee() {
12 @Override
13 public void getSalary() {
14 System.out.println("Employee匿名内部类");
15 }
16 };
17 employee2.getSalary();
18 System.out.println("****************");
19
20 /**
21 * lambda表达式可以看作是一个接口的实例,使用lambda是有前提条件的,就是该接口必须是函数式接口。
22 * 那么什么是函数式接口呢?用一句话总结就是有且仅有一个抽象方法的接口(在java提供的类库中,函数式接口上面都有@FunctionalInterface注解)
23 *
24 * lambda表达式可以总结为:一个(), 一个 ->, 一段代码{}
25 * 一个():参数
26 * 一段代码{}:具体业务逻辑
27 */
28 Employee employee3 = () -> {
29 System.out.println("将上述匿名内部类转为使用lambda表达式");
30 };
31 employee3.getSalary();
32 }
33
34 interface Employee {
35 public void getSalary();
36 }
37
38 static class EmployeeImpl implements Employee {
39
40 @Override
41 public void getSalary() {
42 System.out.print("Employee的普通实现类");
43 }
44 }
45 }
2. Stream流
2.1 函数型接口Function定义
1 package java8;
2
3 import java.util.function.Function;
4
5 /**
6 * 1. 函数型接口Function<T,R>:有输入,有输出
7 * 核心抽象方法为 抽象方法 R apply(T t);
8 */
9 public class FunctionInterface1 {
10
11 public static void main(String[] args) {
12 // 通过lambda实例化一个接口,实现抽象方法R apply(T t);
13 Function<String, Integer> function = (s) -> {
14 if (s == null) {
15 return 0;
16 }
17 return s.length();
18 };
19 Integer result = testFunction("hello", function);
20 System.out.println(result);
21
22 System.out.println("****************");
23 System.out.println(testFunction("hello", s -> {
24 return "更简化的写法".length();
25 }));
26 }
27
28
29 // interface Function<T, R> 抽象方法 R apply(T t);
30 private static Integer testFunction(String str, Function<String, Integer> function) {
31 // str作为第13行的参数s进行传递
32 return function.apply(str);
33 }
34 }
结果
5
****************
6
2.1 函数型接口Function类型
- 函数型接口Function<T,R>
抽象方法 R apply(T t)
- 消费型接口Consumer<T>
- 抽象方法:void accept(T t)
- 供给型接口Supplier<T>
- 抽象方法:T get()
- 断言型接口Predicate<T>
- 抽象方法:boolean test(T t)
1 package java8;
2
3 import java.util.function.Function;
4
5 /**
6 * 1. 函数型接口Function<T,R>:有输入,有输出
7 * 核心抽象方法为 抽象方法 R apply(T t);
8 */
9 public class FunctionInterface1 {
10
11 public static void main(String[] args) {
12 // 通过lambda实例化一个接口,实现抽象方法R apply(T t);
13 Function<String, Integer> function = (s) -> {
14 if (s == null) {
15 return 0;
16 }
17 return s.length();
18 };
19 Integer result = testFunction("hello", function);
20 System.out.println(result);
21
22 System.out.println("****************");
23 System.out.println(testFunction("hello", s -> {
24 return "更简化的写法".length();
25 }));
26 }
27
28
29 // interface Function<T, R> 抽象方法 R apply(T t);
30 private static Integer testFunction(String str, Function<String, Integer> function) {
31 // str作为第13行的参数s进行传递
32 return function.apply(str);
33 }
34 }
1 package java8;
2
3 import java.util.function.Consumer;
4
5 /**
6 * Consumer<T> 消费性接口有输入,但是没有返回值
7 * 抽象方法:void accept(T t);
8 */
9 public class ConsuerFunctionInterface {
10
11 public static void main(String[] args) {
12 // s是实例化方法accept的参数,{}内部是accept的方法体
13 testConsumer(s -> {System.out.println(s);}, "消费性接口抽象方法accept实现");
14 }
15
16 private static void testConsumer(Consumer<String> consumer, String str) {
17 consumer.accept(str);
18 }
19 }
1 package java8;
2
3
4 import java.util.function.Supplier;
5
6 /**
7 * Supplier<T> 供给型接口:无输入、有输出
8 * 抽象方法:T get();
9 */
10 public class SupplierFunctionInterface {
11
12 public static void main(String[] args) {
13
14 // ()是实例化方法T get()参数:即无参数,{}是get的方法体
15 testSupplier(()-> {
16 String name = "Supplier<Person>的抽象方法get实现";
17 System.out.println(name);
18 return new Person(name);
19 });
20 }
21
22 private static Person testSupplier(Supplier<Person> supplier) {
23 return supplier.get();
24 }
25
26 }
27
28 class Person {
29 private static String name;
30
31 Person(String name) {
32 this.name = name;
33 }
34 }
1 package java8;
2
3 import java.util.function.Predicate;
4
5 /**
6 * 断言型接口Predicate<T>
7 * 抽象方法:boolean test(T t);
8 */
9 public class PredicateFunctionInterface {
10
11 public static void main(String[] args) {
12 // b是test方法的参数, {}内部是test方法体
13 boolean res = testPredicate((b) -> {
14 System.out.println("断言型接口Predicate抽象方法boolean test(T t)的实例化");
15 return b > 99;
16 }, 99);
17
18 System.out.println("b>99, res=" + res);
19 }
20
21
22 private static boolean testPredicate(Predicate<Integer> predicate, int a) {
23 return predicate.test(a);
24 }
25 }
2.3 reduce
https://www.cnblogs.com/flydean/p/java-8-stream-reduce.html
https://www.liaoxuefeng.com/wiki/1252599548343744/1322402971648033
https://blog.csdn.net/qq_33351091/article/details/82494855
1 package mtee3rule;
2
3 import java.util.Arrays;
4 import java.util.List;
5 import java.util.Optional;
6
7 public class ReduceTest {
8
9 public static void main(String[] args) {
10 List<Integer> intList = Arrays.asList(1,2,3,4);
11
12 Optional<Integer> result1 = intList.stream().reduce(Integer::sum);
13 System.out.println("result1=" + result1 + ", sum=" + result1.get());
14
15 Integer result2=intList.stream().reduce(100, Integer::sum);
16 System.out.println("result2=" + result2 + ", sum=" + result2);
17
18 // 每个线程的初始累加值都是100,最后4个线程加出来的结果就是406
19 // 这里sum方法的identity只能是0。所以这里我们传入100是不对的,因为sum(100+1)!= 1。
20 // 如果我们用0作为identity,则stream和parallelStream计算出的结果是一样的。这就是identity的真正意图。
21 Integer result3=intList.parallelStream().reduce(100, Integer::sum);
22 System.out.println("result3=" + result2 + ", sum=" + result3);
23
24 testMultiReduce1();
25 }
26
27 private static void testMultiReduce1() {
28 List<String> strings = Arrays.asList("1", "2", "4", "5");
29
30 System.out.println("********in testMultiReduce1()************");
31
32 // 非并行流
33 Integer reduce1 = strings.stream().reduce(0,
34 (acc, e) -> acc + Integer.valueOf(e), (u, t) -> {
35 // 非并行流,不会执行第三个参数
36 System.out.println("u----:" + u);
37 // 这里的返回值并没有影响返回结果
38 return null;
39 });
40 System.out.println("reduce1:" + reduce1);
41
42 // 并行流
43 //System.out.println("out_thread=" + Thread.currentThread().getName());
44 Integer reduce2 = strings.parallelStream().reduce(0,
45 (acc, e) -> acc + Integer.valueOf(e), (u, t) -> {
46 // u,t分别为并行流每个子任务的结果
47 System.out.println("inner_thread=" + Thread.currentThread().getName() + ", u=" + u + ", t=" + t);
48
49 return u + t;
50 });
51 System.out.println("out_thread=" + Thread.currentThread().getName());
52 System.out.println("reduce2:" + reduce2);
53 }
54
55 }
结果:
1 result1=Optional[10], sum=10
2 result2=110, sum=110
3 result3=110, sum=410
4 ********in testMultiReduce1()************
5 reduce1:12
6 inner_thread=ForkJoinPool.commonPool-worker-2, u=1, t=2 // 第一个线程执行
7 inner_thread=main, u=4, t=5 // 第二个线程执行
8 inner_thread=main, u=3, t=9 // u为第6行执行结果3,t为第7行执行结果9
9 out_thread=main
10 reduce2:12 // 第8行执行结果 = 3 + 9
2.4 创建Stream流的方式
2.4.1 ::(双冒号)使用
https://www.jianshu.com/p/96b4815d629e

1 package java8;
2
3 import java.util.Arrays;
4 import java.util.Comparator;
5 import java.util.List;
6 import java.util.Optional;
7
8 public class DoubleMaoHao {
9
10 public static void main(String[] args) {
11 List<String> listStr = Arrays.asList("adnm", "p", "admmt", "pot", "xbangd", "weoujgsd");
12
13 // 最大的串:实例化Comparator的抽象方法int compare(T o1, T o2)
14 // (o1, o2)有两个参数,o1作为当前对象,o2作为参数,都是String;返回值为int —— 其它方法满足这样条件的也可以
15 Optional<String> optionalMax1 = listStr.stream().max(((o1, o2) -> { return o1.compareTo(o2);} ));
16
17 // 简写
18 // 而String::compareTo方法是指int compareTo(String anotherString)--即参数为string,返回值为int的
19 // 其它方法 public int indexOf(String str) --即参数为string,返回值为int的 也可以,但是int length() 无参数的方法就不行
20 Optional<String> optionalMax2 = listStr.stream().max(String::compareTo); // String::length报错
21
22 System.out.println("optionalMax1=" + optionalMax1.get() + ", optionalMax2=" + optionalMax2.get()); // optionalMax3=adnm, optionalMax4=w3
23
24
25 List<String> listStr3 = Arrays.asList("adnm", "dn", "n");
26 List<String> listStr4 = Arrays.asList("adnm", "w3", "3");
27 Optional<String> optionalMax3 = listStr3.stream().max(String::indexOf); // adnm.indexOf("dn")>0, "dn".indexOf("n")>0
28 Optional<String> optionalMax4 = listStr4.stream().max(String::indexOf); // adnm.indexOf("w3")<0, "w3".indexOf("3")>0
29 System.out.println("optionalMax3=" + optionalMax3.get() + ", optionalMax4=" + optionalMax4.get()); // optionalMax3=adnm, optionalMax4=w3
30
31 Optional<String> optionalMax5 = listStr.stream().max((o1,o2) -> {return 1;}); // >=0:adnm 即两两比较 前面最大; <0,则最后一个最大
32 System.out.println("optionalMax5=" + optionalMax5.get()); // max=adnm (第0个)
33
34 Optional<String> optionalMax6 = listStr.stream().max((o1,o2) -> {return -1;}); // >=0:adnm 即两两比较 前面最大; <0,则最后一个最大
35 System.out.println("optionalMax6=" + optionalMax6.get()); // max=weoujgsd (最后一个)
36
37
38 /**
39 * max()方法中需要一个函数式接口Comparator<T>
40 * comparing方法中需要一个函数型接口Function<T, R>,唯一的抽象方法为R apply(T t);
41 * x作为Function方法的参数,到了Function方法体里 x作为对象来调用 无参数方法(这里x是String类型,则可以调用String的所有无参方法且返回值为int)
42 */
43 Optional<String> max1 = listStr.stream().max(Comparator.comparing((x) -> {
44 return x.length();
45 }));
46 Optional<String> max2 = listStr.stream().max(Comparator.comparing((x) -> {
47 return 1;
48 }));
49 Optional<String> max3 = listStr.stream().max(Comparator.comparing((x) -> {
50 return -1;
51 }));
52 // 要看comparing内部的实现Function keyExtractor (c1, c2) -> keyExtractor.apply(c1).compareTo(keyExtractor.apply(c2));
53 System.out.println("max1=" + max1.get() + ", max2=" + max2.get() + ", max3=" + max3.get()); // max1=weoujgsd, max2=adnm, max3=adnm
54
55 // 简写形式——使用了静态方法Comparator.comparing,比较的是length属性,
56 Optional<String> max1_1 = listStr.stream().max(Comparator.comparing(String::length)); // String::compareTo报错
57 System.out.println("简写_最长的字符串 max1_1:" + max1_1.get());
58 }
59 }
结果:
optionalMax1=xbangd, optionalMax2=xbangd
optionalMax3=adnm, optionalMax4=w3
optionalMax5=adnm
optionalMax6=weoujgsd
max1=weoujgsd, max2=adnm, max3=adnm
简写_最长的字符串 max1_1:weoujgsd
参考文献:
1.https://zhuanlan.zhihu.com/p/340538961
2.https://blog.csdn.net/yczz/article/details/50896975
3.https://blog.csdn.net/love905661433/article/details/86422169
Java8新特性(Lambda表达式、Stream流、Optional类)等的更多相关文章
- Java8新特性-Lambda表达式是什么?
目录 前言 匿名内部类 函数式接口 和 Lambda表达式语法 实现函数式接口并使用Lambda表达式: 所以Lambda表达式是什么? 实战应用 总结 前言 Java8新特性-Lambda表达式,好 ...
- 乐字节-Java8新特性-Lambda表达式
上一篇文章我们了解了Java8新特性-接口默认方法,接下来我们聊一聊Java8新特性之Lambda表达式. Lambda表达式(也称为闭包),它允许我们将函数当成参数传递给某个方法,或者把代码本身当作 ...
- Java8新特性之空指针异常的克星Optional类
Java8新特性系列我们已经介绍了Stream.Lambda表达式.DateTime日期时间处理,最后以"NullPointerException" 的克星Optional类的讲解 ...
- java8新特性——Lambda表达式
上文中简单介绍了一下java8得一些新特性,与优点,也是为本次学习java8新特性制定一个学习的方向,后面几篇会根据上文中得新特性一一展开学习.本文就从java8新特性中比较重要的Lambda表达式开 ...
- Java8新特性 - Lambda表达式 - 基本知识
A lambda expression is an unnamed block of code (or an unnamed function) with a list of formal param ...
- 深度分析:java8的新特性lambda和stream流,看完你学会了吗?
1. lambda表达式 1.1 什么是lambda 以java为例,可以对一个java变量赋一个值,比如int a = 1,而对于一个方法,一块代码也是赋予给一个变量的,对于这块代码,或者说被赋给变 ...
- java8新特性-lambda表达式和stream API的简单使用
一.为什么使用lambda Lambda 是一个 匿名函数,我们可以把 Lambda表达式理解为是 一段可以传递的代码(将代码像数据一样进行传递).可以写出更简洁.更灵活的代码.作为一种更紧凑的代码风 ...
- java8新特性Lambda和Stream
Java8出来已经4年,但还是有很多人用上了jdk8,但并没用到里面的新东西,那不就等于没用?jdk8有许多的新特性,详细可看下面脑图 我只讲两个最重要的特性Lambda和Stram,配合起来用可以极 ...
- Java8新特性: lambda 表达式介绍
一.lambda 表达式介绍 lambda 表达式是 Java 8 的一个新特性,可以取代大部分的匿名内部类,简化了匿名委托的使用,让你让代码更加简洁,优雅. 比较官方的定义是这样的: lambda ...
- Java8 新特性lambda表达式(一)初始
本篇参考Richard Warburton的 java8 Lambdas :Functional Programming for the Masses 学习lambda表达式之前,需要知道什么是函数式 ...
随机推荐
- FireflySoft.LeaderElection增加基于ZooKeeper的Leader选举
FireflySoft.LeaderElection的第一个版本实现了基于Consul的Leader选举,考虑到ZooKeeper的一个常见用途也是选主,所以此类库把ZooKeeper也集成了进来.并 ...
- ubuntu下安装mysqlclient报错
输入以下代码: 1 解决方法: 2 sudo apt-get install libmysqlclient-dev 3 4 再次安装: 5 pip3 install mysqlclient 文章链接: ...
- 代码随想录算法训练营第八天| LeetCode 344.反转字符串 541. 反转字符串II 151.翻转字符串里的单词
344.反转字符串 卡哥建议: 本题是字符串基础题目,就是考察 reverse 函数的实现,同时也明确一下 平时刷题什么时候用 库函数,什么时候 不用库函数 题目链接/文章讲解/视频讲解:https: ...
- Hi3798MV200 恩兔N2 NS-1 (二): HiNAS海纳思使用和修改
目录 Hi3798MV200 恩兔N2 NS-1 (一): 设备介绍和刷机说明 Hi3798MV200 恩兔N2 NS-1 (二): HiNAS海纳思使用和修改 Hi3798MV200 恩兔N2 NS ...
- Hadoop集群启动没有DataNode进程
问题状况: 问题原因: 在启动Hadoop之前,进行了多次格式化,导致DataNode的ID发生了变化 解决方案: 我们可以删除从节点所有的DataNode资料,并重新格式化 解决流程 1.根据cor ...
- [jmeter]简介与安装
简介 JMeter是开源软件Apache基金会下的一个性能测试工具,用来测试部署在服务器端的应用程序的性能. 安装 安装jmeter 从 官网 下载jmeter的压缩包 安装jdk并配置 JAVA_H ...
- php批量同步数据
php批量同步流程 首先分页获取数据 创建临时表 批量添加数据 备份原表 删除原表 修改临时表表名改为原表 代码 1 <?php 2 3 class Stock{ 4 5 private $da ...
- win10右键添加打开cmd窗口的命令
创建文本文档,复制如下内容: Windows Registry Editor Version 5.00 [HKEY_LOCAL_MACHINE\SOFTWARE\Classes\Directory\b ...
- 2023-08-12:用go语言写算法。实验室需要配制一种溶液,现在研究员面前有n种该物质的溶液, 每一种有无限多瓶,第i种的溶液体积为v[i],里面含有w[i]单位的该物质, 研究员每次可以选择一瓶
2023-08-12:用go语言写算法.实验室需要配制一种溶液,现在研究员面前有n种该物质的溶液, 每一种有无限多瓶,第i种的溶液体积为v[i],里面含有w[i]单位的该物质, 研究员每次可以选择一瓶 ...
- python flask 简单应用开发
转载请注明出处: Flask 是一个基于 Python 的微型 Web 框架,它提供了一组简洁而强大的工具和库,用于构建 Web 应用程序.Flask 的主要作用是帮助开发者快速搭建轻量级的.灵活的 ...