jdk新特性

前言

熟练掌握、使用jdk8新特性。

本篇主要讲述是JavaJDK1.8的一些新语法特性使用,主要是LambdaStream的一些使用讲解。

JDK8的Lambda、Stream和日期的使用详解:https://blog.csdn.net/hanshanyunhai/article/details/109117303

一、Lambda

1.1 Lambda介绍

1、Lambda 表达式(lambda expression)是一个匿名函数,Lambda表达式基于数学中的λ演算得名,直接对应于其中的lambda抽象(lambda abstraction),是一个匿名函数,即没有函数名的函数。

2、Lambda表达式叫做函数式编程思想概述(函数式思想是尽量忽略面向对象的复杂语法:强调做什么,而不是以什么形式去做

3、可以类比为将一段代码块,赋值给一个匿名变量;相较于传统的编码方式,使代码变得异常整洁;相对的,可读性有所下降。

1.2 Lambda表达式的结构

1、格式:(形式参数)->{代码块}

  1. ():形式参数:如果多个参数,参数之间用逗号隔开,如果没有参数,留空即可里面没有内容,可以看成是方法形式参数为空
  2. ->:由英文中画线和大于符号组成,固定写法。用箭头指向后面要做的事情
  3. {}:包含一段代码,我们称之为代码块,是我们具体要做的事情可以看成是方法体中的内容
  4. 组成Lambda表达式的三要素:形式参数,箭头,代码块

2、说明

一个 Lambda 表达式可以有零个或多个参数

 

参数的类型既可以明确声明,也可以根据上下文来推断。例如:(int a)(a)效果相同

 

所有参数需包含在圆括号内,参数之间用逗号相隔。例如:(a, b) (int a, int b) (String a, int b, float c)

 

空圆括号代表参数集为空。例如:() -> 42

 

当只有一个参数,且其类型可推导时,圆括号()可省略。例如:a -> return a*a

 

Lambda 表达式的主体可包含零条或多条语句

 

如果 Lambda 表达式的主体只有一条语句,花括号{}可省略。匿名函数的返回类型与该主体表达式一致

 

如果 Lambda 表达式的主体包含一条以上语句,则表达式必须包含在花括号{}中(形成代码块)。匿名函数的返回类型与代码块的返回类型一致,若没有返回则为空

 

1.3 Lambda 表达式的使用

1、list的遍历

list.forEach(v -> {

System.out.println(v);

});

2、Map的遍历

map.forEach((k, v) -> {

            System.out.println("k=" + k + "v=" + v);

        });

3、代替匿名内部类

4、其他用法

二、Stream

2.1介绍

1、概念:StreamJava8 API的新成员,它允许以声明性方式处理数据集合 。

2、说明:Stream使用一种类似用 SQL 语句从数据库查询数据的直观方式来提供一种对 Java 集合运算和表达的高阶抽象。Stream API可以极大提高Java程序员的生产力,让程序员写出高效率、干净、简洁的代码。这种风格将要处理的元素集合看作一种流, 流在管道中传输, 并且可以在管道的节点上进行处理, 比如筛选, 排序,聚合等。

3、代码简洁:函数式编程写出的代码简洁且意图明确,使用stream接口让你从此告别for循环。

4、多核友好:Java函数式编程使得编写并行程序从未如此简单,你需要的全部就是调用一下方法。

2.2 Stream流程

1)第一步:把集合转换为流stream

2)第二步:操作stream:stream流在管道中经过中间操作(intermediate operation)的处理

3)最后由最终操作(terminal operation)得到前面处理的结果

2.3 Stream 流操作类型

1、操作符:两种:中间操作符、终止操作符

Intermediate:一个流可以后面跟随零个或多个 intermediate 操作。其目的主要是打开流,做出某种程度的数据映射/过滤,然后返回一个新的流,交给下一个操作使用。这类操作都是惰性化的(lazy),就是说,仅仅调用到这类方法,并没有真正开始流的遍历。

Terminal:一个流只能有一个 terminal 操作,当这个操作执行后,流就被使用了,无法再被操作。所以这必定是流的最后一个操作。Terminal操作的执行,才会真正开始流的遍历,并且会生成一个结果,或者一个 side effect

2.4 Stream使用

1、中间操作符

流方法

含义

示例

filter

用于通过设置的条件过滤出元素

List strings = Arrays.asList(“abc”, “”, “bc”, “efg”, “abcd”,"", “jkl”);List filtered = strings.stream().filter(string -> !string.isEmpty()).collect(Collectors.toList());

distinct

返回一个元素各异(根据流所生成元素的hashCode和equals方法实现)的流。

List numbers = Arrays.asList(1, 2, 1, 3, 3, 2, 4);numbers.stream().filter(i -> i % 2 == 0).distinct().forEach(System.out::println);

limit

会返回一个不超过给定长度的流。

List strings = Arrays.asList(“abc”, “abc”, “bc”, “efg”, “abcd”,“jkl”, “jkl”);List limited = strings.stream().limit(3).collect(Collectors.toList());

skip

返回一个扔掉了前n个元素的流。

List strings = Arrays.asList(“abc”, “abc”, “bc”, “efg”, “abcd”,“jkl”, “jkl”);List skiped = strings.stream().skip(3).collect(Collectors.toList());

map

接受一个函数作为参数。这个函数会被应用到每个元素上,并将其映射成一个新的元素(使用映射一词,是因为它和转换类似,但其中的细微差别在于它是“创建一个新版本”而不是去“修改”)。

List strings = Arrays.asList(“abc”, “abc”, “bc”, “efg”, “abcd”,“jkl”, “jkl”);List mapped = strings.stream().map(str->str+"-itcast").collect(Collectors.toList());

flatMap

使用flatMap方法的效果是,各个数组并不是分别映射成一个流,而是映射成流的内容。所有使用map(Arrays::stream)时生成的单个流都被合并起来,即扁平化为一个流。

List strings = Arrays.asList(“abc”, “abc”, “bc”, “efg”, “abcd”,“jkl”, “jkl”);Stream flatMap = strings.stream().flatMap(Java8StreamTest::getCharacterByString);

sorted

返回排序后的流

List strings1 = Arrays.asList(“abc”, “abd”, “aba”, “efg”, “abcd”,“jkl”, “jkl”);List sorted1 = strings1.stream().sorted().collect(Collectors.toList());

MapflatMap区别:

map:对流中每一个元素进行处理

flatMap:流扁平化,让你把一个流中的“每个值”都换成另一个流,然后把所有的流连接起来成为一个流

总结:map是对一级元素进行操作,flatmap是对二级元素操作。

本质区别:map返回一个值;flatmap返回一个流,多个值。

应用场景:map对集合中每个元素加工,返回加工后结果;flatmap对集合中每个元素加工后,做扁平化处理后(拆分层级,放到同一层)然后返回。

 

https://blog.csdn.net/m0_49102380/article/details/123830542

 

2、终止操作符

流方法

含义

示例

anyMatch

检查是否至少匹配一个元素,返回boolean。

List strings = Arrays.asList(“abc”, “abd”, “aba”, “efg”, “abcd”,“jkl”, “jkl”);boolean b = strings.stream().anyMatch(s -> s == “abc”);

allMatch

检查是否匹配所有元素,返回boolean。

List strings = Arrays.asList(“abc”, “abd”, “aba”, “efg”, “abcd”,“jkl”, “jkl”);boolean b = strings.stream().allMatch(s -> s == “abc”);

noneMatch

检查是否没有匹配所有元素,返回boolean。

List strings = Arrays.asList(“abc”, “abd”, “aba”, “efg”, “abcd”,“jkl”, “jkl”);boolean b = strings.stream().noneMatch(s -> s == “abc”);

findAny

将返回当前流中的任意元素。

List strings = Arrays.asList(“cv”, “abd”, “aba”, “efg”, “abcd”,“jkl”, “jkl”);Optional any = strings.stream().findAny();

findFirst

返回第一个元素

List strings = Arrays.asList(“cv”, “abd”, “aba”, “efg”, “abcd”,“jkl”, “jkl”);Optional first = strings.stream().findFirst();

forEach

遍历流

List strings = Arrays.asList(“cv”, “abd”, “aba”, “efg”, “abcd”,“jkl”, “jkl”);strings.stream().forEach(s -> out.println(s));

collect

收集器,将流转换为其他形式。

List strings = Arrays.asList(“cv”, “abd”, “aba”, “efg”, “abcd”,“jkl”, “jkl”);Set set = strings.stream().collect(Collectors.toSet());List list = strings.stream().collect(Collectors.toList());Map<String, String> map = strings.stream().collect(Collectors.toMap(v ->v.concat("_name"), v1 -> v1, (v1, v2) -> v1));

reduce

可以将流中元素反复结合起来,得到一个值。

List strings = Arrays.asList(“cv”, “abd”, “aba”, “efg”, “abcd”,“jkl”, “jkl”);Optional reduce = strings.stream().reduce((acc,item) -> {return acc+item;});if(reduce.isPresent())out.println(reduce.get());

count

返回流中元素总数。

List strings = Arrays.asList(“cv”, “abd”, “aba”, “efg”, “abcd”,“jkl”, “jkl”);long count = strings.stream().count();

三、Lambda 双冒号:: 流式编程

https://blog.csdn.net/lsmsrc/article/details/41747159

其他、map新增的方法opition

看类serialNOservice中Map相关的方法
 
posted @ 2021-10-01 22:49  慎终若始  阅读(30)  评论(0编辑  收藏  举报