JDK1.8新特性——Lambda详解
前言
本篇主要讲述是Java中JDK1.8的一些新语法特性使用,主要是Lambda、Stream和LocalDate日期的一些使用讲解。
Lambda
- Lambda 表达式,也可称为闭包,它是推动 Java 8 发布的最重要新特性。
- Lambda 允许把函数作为一个方法的参数(函数作为参数传递进方法中)。
- 使用 Lambda 表达式可以使代码变的更加简洁紧凑。
Lambda 表达式(lambda expression)是一个匿名函数,Lambda表达式基于数学中的λ演算得名,直接对应于其中的lambda抽象(lambda abstraction),是一个匿名函数,即没有函数名的函数。
1.Lambda表达式的结构
(parameters) -> expression 或 (parameters) ->{ statements; }
使用Lambda进行遍历:
System.out.println("map拉姆达表达式遍历:");
map.forEach((k, v) -> {
System.out.println("k=" + k + ",v=" + v);
});
2.Stream
Stream 使用一种类似用 SQL 语句从数据库查询数据的直观方式来提供一种对 Java 集合运算和表达的高阶抽象。Stream API可以极大提高Java程序员的生产力,让程序员写出高效率、干净、简洁的代码。这种风格将要处理的元素集合看作一种流, 流在管道中传输, 并且可以在管道的节点上进行处理, 比如筛选, 排序,聚合等。
java.util.stream.Collectors,是从JDK1.8开始新引入的一个类。从源码的类注释上,我们可以知道:
Collectors实现了各种有用归约的操作,例如类型归类到新集合、根据不同标准汇总元素等。透过示例,能让我们眼前一亮,短短的一行代码却能处理如此强大、复杂的功能:汇总、拼接、累加计算、分组等。
Collectors使用:
* Set<String> set = people.stream().map(Person::getName).collect(Collectors.toCollection(TreeSet::new));
*
* // Convert elements to strings and concatenate them, separated by commas
* String joined = things.stream()
* .map(Object::toString)
* .collect(Collectors.joining(", "));
filter使用:
List<String> list = Arrays.asList("张三", "李四", "王五", "xuwujing");
String result3 = list.stream().filter(str -> "李四".equals(str)).findAny().orElse("找不到!");
String result4 = list.stream().filter(str -> "李二".equals(str)).findAny().orElse("找不到!");
//stream 过滤之后 2:李四
//stream 过滤之后 3:找不到!
limit使用:
Random rd = new Random();
System.out.println("取到的前三条数据:");
rd.ints().limit(3).forEach(System.out::println);
分组:groupingBy/groupingByConcurrent
按照条件对元素进行分组,和 SQL 中的 group by 用法有异曲同工之妙,通常也建议使用Java代码进行分组处理以减轻数据库SQL压力。
分组涉及以下方法:
- Collectors.groupingBy(…):普通分组。
- Collectors.groupingByConcurrent(…):线程安全的分组。
分组后,返回的是一个Map集合,其中key作为分组对象,value作为对应分组结果。
比如,考虑到People集合中可能会存在同龄人,将集合按照年龄进行分组:
Map<Integer, List<People>> groupingByAge = allPeoples.stream().collect(Collectors.groupingBy(People::getAge));
3.LocalDate
- Instant:瞬时时间。
- LocalDate:本地日期,不包含具体时间, 格式 yyyy-MM-dd。
- LocalTime:本地时间,不包含日期. 格式 yyyy-MM-dd HH:mm:ss.SSS 。
- LocalDateTime:组合了日期和时间,但不包含时差和时区信息。
- ZonedDateTime:最完整的日期时间,包含时区和相对UTC或格林威治的时差。
//获取当前的时间,包括毫秒
LocalDateTime ldt = LocalDateTime.now();
System.out.println("当前年:"+ldt.getYear()); //2021
System.out.println("当前年份天数:"+ldt.getDayOfYear());//172
System.out.println("当前月:"+ldt.getMonthValue());
System.out.println("当前时:"+ldt.getHour());
System.out.println("当前分:"+ldt.getMinute());
System.out.println("当前时间:"+ldt.toString());
// 当前年:2021
// 当前年份天数:365
// 当前月:8
// 当前时:10
// 当前分:24
// 当前时间:2021-8-1T15:24:35.833
JVM新特性
JDK8在JVM中修改重要有:
- 新增JVM工具:jdeps提供了用于分析类文件的命令行工具。
- 使用metaSpace代替永久区
- 新增NMT(Native Memeory Trace)本地内存跟踪器
HashMap变化
JDK8优化了HashMap的实现, 主要优化点包括:
- 将链表方式修改成链表或者红黑树的形式
- 修改resize的过程,解决JDK7在resize在并发场景下死锁的隐患
- JDK1.7存储使用Entry数组, JDK8使用Node或者TreeNode数组存储
当链表长度大于8是链表的存储结构会被修改成红黑树的形式。
查询效率从O(N)提升到O(logN)。链表长度小于6时,红黑树的方式退化成链表。
JDK7链表插入是从链表头部插入, 在resize的时候会将原来的链表逆序。
JDK8插入从链表尾部插入, 因此在resize的时候仍然保持原来的顺序。
作者:undeifined
链接:https://juejin.cn/post/6991624440777801759
来源:掘金