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类)等的更多相关文章

  1. Java8新特性-Lambda表达式是什么?

    目录 前言 匿名内部类 函数式接口 和 Lambda表达式语法 实现函数式接口并使用Lambda表达式: 所以Lambda表达式是什么? 实战应用 总结 前言 Java8新特性-Lambda表达式,好 ...

  2. 乐字节-Java8新特性-Lambda表达式

    上一篇文章我们了解了Java8新特性-接口默认方法,接下来我们聊一聊Java8新特性之Lambda表达式. Lambda表达式(也称为闭包),它允许我们将函数当成参数传递给某个方法,或者把代码本身当作 ...

  3. Java8新特性之空指针异常的克星Optional类

    Java8新特性系列我们已经介绍了Stream.Lambda表达式.DateTime日期时间处理,最后以"NullPointerException" 的克星Optional类的讲解 ...

  4. java8新特性——Lambda表达式

    上文中简单介绍了一下java8得一些新特性,与优点,也是为本次学习java8新特性制定一个学习的方向,后面几篇会根据上文中得新特性一一展开学习.本文就从java8新特性中比较重要的Lambda表达式开 ...

  5. Java8新特性 - Lambda表达式 - 基本知识

    A lambda expression is an unnamed block of code (or an unnamed function) with a list of formal param ...

  6. 深度分析:java8的新特性lambda和stream流,看完你学会了吗?

    1. lambda表达式 1.1 什么是lambda 以java为例,可以对一个java变量赋一个值,比如int a = 1,而对于一个方法,一块代码也是赋予给一个变量的,对于这块代码,或者说被赋给变 ...

  7. java8新特性-lambda表达式和stream API的简单使用

    一.为什么使用lambda Lambda 是一个 匿名函数,我们可以把 Lambda表达式理解为是 一段可以传递的代码(将代码像数据一样进行传递).可以写出更简洁.更灵活的代码.作为一种更紧凑的代码风 ...

  8. java8新特性Lambda和Stream

    Java8出来已经4年,但还是有很多人用上了jdk8,但并没用到里面的新东西,那不就等于没用?jdk8有许多的新特性,详细可看下面脑图 我只讲两个最重要的特性Lambda和Stram,配合起来用可以极 ...

  9. Java8新特性: lambda 表达式介绍

    一.lambda 表达式介绍 lambda 表达式是 Java 8 的一个新特性,可以取代大部分的匿名内部类,简化了匿名委托的使用,让你让代码更加简洁,优雅. 比较官方的定义是这样的: lambda ...

  10. Java8 新特性lambda表达式(一)初始

    本篇参考Richard Warburton的 java8 Lambdas :Functional Programming for the Masses 学习lambda表达式之前,需要知道什么是函数式 ...

随机推荐

  1. 号外号外!首届开源 AI 游戏挑战赛圆满结束!

    北京时间 7 月 8 日到 7 月 10 日, 我们举办了 首届开源 AI 游戏开发挑战赛.这是一场激动人心的赛事活动,游戏开发者在紧迫的 48 小时内使用 AI 创造.创新有创意的游戏. 本次赛事活 ...

  2. 【技术积累】Linux中的命令行【理论篇】【一】

    7z命令 命令介绍 7z命令是Linux系统中的一个压缩和解压缩工具,它可以用来创建.压缩和解压缩7z格式的文件.7z是一种高压缩率的文件格式,通常比其他常见的压缩格式(如zip和gzip)具有更高的 ...

  3. 26194136 psu安装步骤

    26194136 psu安装步骤 1.拷贝 安装包p26194136_112040_MSWIN-x86-64.zip到 目录 2..关闭rac crsctl stop crs srvctl stop ...

  4. Canvas好难,如何让研发低成本实现Web端流程图设计功能

    摘要:本文由葡萄城技术团队于博客园原创并首发.转载请注明出处:葡萄城官网,葡萄城为开发者提供专业的开发工具.解决方案和服务,赋能开发者. 前言 相信大家在职场中经常会用到流程图,在互联网行业,绘制流程 ...

  5. 使用supervisor守护freeswitch进程

    一.安装supervisor yum install -y epel-release yum install -y supervisor systemctl start supervisord sys ...

  6. 【go笔记】从安装到helloworld

    前言 Go语言也称Golang,google出品,特点在于编程简便的同时并发性能不俗. 环境准备: Go语言版本:1.17.2.安装包下载链接:https://studygolang.com/dl l ...

  7. CentOS7系统初始化个人配置

    以下内容为个人最小化安装后的配置步骤 更换yum源为阿里云 yum install -y epel-release lrzsz wget yum-axelget mv /etc/yum.repos.d ...

  8. debian11编译安装freeswitch

    前言 环境: 系统版本:debian 11 x86_64 FreeSWITCH版本:1.10.6 安装步骤 安装依赖(安装之前最好换apt软件源为国内的) apt install -y gnupg2 ...

  9. Kurator,你的分布式云原生解决方案

    本文分享自华为云社区<DTSE Tech Talk | 第40期:Kurator,你的分布式云原生解决方案>,作者:华为云社区精选. 什么是分布式云原生? 中国信通院给出的定义:分布式云原 ...

  10. 千万级数据的表,我把慢sql优化后性能提升30倍!

    分享技术,用心生活 背景:系统中有一个统计页面加载特别慢,前端设置的40s超时时间都加载不出来数据,因为是个统计页面,基本上一猜就知道是mysql的语句有问题,遗留了很久没有解决,正好趁不忙的时候,下 ...