jdk新特性
前言
本篇主要讲述是Java中JDK1.8的一些新语法特性使用,主要是Lambda、Stream的一些使用讲解。
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、格式:(形式参数)->{代码块}
- ():形式参数:如果多个参数,参数之间用逗号隔开,如果没有参数,留空即可。里面没有内容,可以看成是方法形式参数为空。
- ->:由英文中画线和大于符号组成,固定写法。用箭头指向后面要做的事情。
- {}:包含一段代码,我们称之为代码块,是我们具体要做的事情,可以看成是方法体中的内容。
- 组成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、概念:Stream是Java8 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()); |
Map、flatMap区别:
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
在所有的矛盾中,要优先解决主要矛盾,其他矛盾也就迎刃而解。
不要做个笨蛋,为失去的郁郁寡欢,聪明的人,已经找到了解决问题的办法,或正在寻找。