1、Lambda演变过程

@Data

@ToString

@NoArgsConstructor

@AllArgsConstructorpublic classStudent {//名字

privateString name;//性别

privateString sex;//薪水

private intsalary;//年龄

private intage;//星座

privateString star;

}

1.1、普通筛选

将这个集合遍历,然后依次的判断,这是最为普通的一种方式。

@Testpublic voidtest1(){//首先创建一个

List list =Arrays.asList(new Student("九天","男",5000,18,"天秤座"),new Student("十夜","男",4000,16,"双鱼座"),new Student("十一郎","男",3000,24,"水瓶座")

);

List result = new ArrayList<>();for(Student student:list){if ("天秤座".equals(student.getStar())){

result.add(student);

}

}

System.out.println(result);

}

1.2、匿名内部类筛选

通过匿名内部类的方法,在内部类中添加判断条件进行筛选,首先创建一个公共接口:

public interface FilterProcess{booleanprocess(T t);

}

接下来通过一个公共函数,对集合以及筛选条件做一个共同方法,筛选到班级里星座是天秤星座的学生

public List filterStudent(List students, FilterProcessmp){

List list = new ArrayList<>();for(Student student : students) {if(mp.process(student)){

list.add(student);

}

}returnlist;

}

最后是通过匿名内部类和该方法得到结果:

@Testpublic voidtest2(){

List students =Arrays.asList(new Student("九天","男",5000,18,"天秤座"),new Student("十夜","男",4000,16,"双鱼座"),new Student("十一郎","男",3000,24,"水瓶座")

);

List list = filterStudent(students, new FilterProcess() {

@Overridepublic booleanprocess(Student student) {return student.getStar().equals("天秤座");

}

});for(Student student : list) {

System.out.println(student);

}

}

结果如图:

1.3、半Lambda方法

但是通过这两种代码都是很多,所以java8在这一点上提供了对集合筛选最大程度的删减代码,就是第三种方法。第三种方法:通过Lambda直接判断,一步到位,不需要在写其他的方法。

@Testpublic voidtest3(){

List list =Arrays.asList(new Student("九天","男",5000,18,"天秤座"),new Student("十夜","男",4000,16,"双鱼座"),new Student("十一郎","男",3000,24,"水瓶座")

);

List result = filterStudent(list,(e)->e.getStar().equals("天秤座"));

System.out.println(result);

}

测试结果:

但是现在又会有人会问这个问题,我的那个方法中是这样子的

filterStudent(List students, FilterProcess mp)

为什么我的代码参数却是这样子的呢

filterStudent(list,(e)->e.getStar().equals("天秤座")

其实 -> 这个是一个连接符,左边代表参数,而右边代表函数体(也就是我们说的条件),这个e就是代表  FilterProcess mp 这个参数的,只不过我们得java8 中lambda可以给这个参数附加上了条件,这些条件筛选都是封装到jdk8中内部类中自己实现的,所以我们只要附加条件就可以了,那个(e)就代表传了参数。

1.4、真正运用lambda方法

@Testpublic voidtest1() {

List list =Arrays.asList(new Student("九天","男",5000,18,"天秤座"),new Student("十夜","男",4000,16,"双鱼座"),new Student("十一郎","男",3000,24,"水瓶座")

);

list.stream().filter((e)-> e.getStar().equals("天秤座"))

.forEach(System.out::println);

}

结果依然是相同的答案,直到第4个方法出来,对比前三个方法,简单了很多,这就是我们lambda演练的过程。

总结:lambda主要是针对集合中条件的筛选,包括数组等等。接下来我们介绍Stream API ,这个和Lambda息息相关,论重要性,lambda只是基础,Stream API 才是真正的升级版

2、StreamAPI详解

2.0、功能

父类:BasicStream

子类:Stream、IntStream、LongStream、DoubleStream

包含两个类型,中间操作(intermediate operations)和结束操作(terminal operations)

下面是所有方法的属于那一端操作的方法:

然后准备一个测试类,和一个静态变量,图下:

public classJdkTest {public static List list =Arrays.asList(new Student("九天", "男", 5000, 18, "天秤座"),new Student("十夜", "男", 4000, 16, "双鱼座"),new Student("十一郎", "男", 3000, 24, "水瓶座")

);

}

接下来我们一个一个方法解析他们的作用

2.1、stream

将集合转换成流,一般会使用流继续后续操作。

@Testpublic voidtest0() {

list.stream();

}

2.2、forEach遍历

forEach遍历集合,System.out::println等同于System.out.println()

@Testpublic voidtest1() {

list.forEach(System.out::println);

}

结果为:

2.3、filter过滤

该方法中是一个筛选条件,等同于sql查询的where后面的筛选。

@Testpublic voidtest2() {

list.stream().filter((e)-> e.getStar().equals("天秤座"))

.forEach(System.out::println);

}

2.4、map转换集合

将List 转换为List, collect是将结果转换为List

@Testpublic voidtest3() {

List names =list.stream().map(Student::getName).collect(Collectors.toList());

names.stream().forEach(System.out::println);

}

结果:

2.5、mapToInt转换数值流

转换数值流,等同mapToLong、mapToDouble,如下这个是取最大值

@Testpublic voidtest4() {

IntStream intStream=list.stream().mapToInt(Student::getAge);

Stream integerStream =intStream.boxed();

Optional max =integerStream.max(Integer::compareTo);

System.out.println(max.get());

}

结果为:

24

2.6、flatMap合并成一个流

将流中的每一个元素 T 映射为一个流,再把每一个流连接成为一个流

@Testpublic voidtest5() {

List list2 = new ArrayList<>();

list2.add("aaa bbb ccc");

list2.add("ddd eee fff");

list2.add("ggg hhh iii");

list2= list2.stream().map(s -> s.split(" ")).flatMap(Arrays::stream).collect(Collectors.toList());

System.out.println(list2);

}

结果为:

[aaa, bbb, ccc, ddd, eee, fff, ggg, hhh, iii]

2.7、distinct去重

@Testpublic voidtest6() {

List list2 = new ArrayList<>();

list2.add("aaa bbb ccc");

list2.add("ddd eee fff");

list2.add("ggg hhh iii");

list2.add("ggg hhh iii");

list2.stream().distinct().forEach(System.out::println);

}

结果:

aaa bbb ccc

ddd eee fff

ggg hhh iii

2.8、sorted排序

@Testpublic voidtest7() {//asc排序

list.stream().sorted(Comparator.comparingInt(Student::getAge)).forEach(System.out::println);

System.out.println("------------------------------------------------------------------");//desc排序

list.stream().sorted(Comparator.comparingInt(Student::getAge).reversed()).forEach(System.out::println);

}

结果:

Student(name=十夜, sex=男, salary=4000, age=16, star=双鱼座)

Student(name=九天, sex=男, salary=5000, age=18, star=天秤座)

Student(name=十一郎, sex=男, salary=3000, age=24, star=水瓶座)

------------------------------------------------------------------

Student(name=十一郎, sex=男, salary=3000, age=24, star=水瓶座)

Student(name=九天, sex=男, salary=5000, age=18, star=天秤座)

Student(name=十夜, sex=男, salary=4000, age=16, star=双鱼座)

2.9、skip跳过前n个

@Testpublic voidtest8() {

list.stream().skip(1).forEach(System.out::println);

}

2.10、limit截取前n个

@Testpublic voidtest10() {

list.stream().limit(1).forEach(System.out::println);

}

结果为:

Student(name=九天, sex=男, salary=5000, age=18, star=天秤座)

2.11、anyMatch

只要有其中任意一个符合条件

@Testpublic voidtest11() {boolean isHave = list.stream().anyMatch(student -> student.getAge() == 16);

System.out.println(isHave);

}

2.12、allMatch

全部符合

@Testpublic voidtest12() {boolean isHave = list.stream().allMatch(student -> student.getAge() == 16);

System.out.println(isHave);

}

2.13、noneMatch

是否满足没有符合的

@Testpublic voidtest13() {boolean isHave = list.stream().noneMatch(student -> student.getAge() == 16);

System.out.println(isHave);

}

2.14、findAny

找到其中一个元素 (使用 stream() 时找到的是第一个元素;使用 parallelStream() 并行时找到的是其中一个元素)

@Testpublic voidtest14() {

Optional student =list.stream().findAny();

System.out.println(student.get());

}

2.15、findFirst

找到第一个元素

@Testpublic voidtest15() {

Optional student =list.stream().findFirst();

System.out.println(student.get());

}

2.17、count计数

@Testpublic voidtest17() {long count =list.stream().count();

System.out.println(count);

}

2.18、of

生成一个字符串流

@Testpublic voidtest18() {

Stream stringStream = Stream.of("i","love","you");

}

2.19、empty

生成一个空流

@Testpublic voidtest19() {

Stream stringStream =Stream.empty();

}

2.20、iterate

@Testpublic voidtest20() {

List list = Arrays.asList("a", "b", "c", "c", "d", "f", "a");

Stream.iterate(0, i -> i + 1).limit(list.size()).forEach(i ->{

System.out.println(String.valueOf(i)+list.get(i));

});

}

2.21、collect:averagingLong

求平均值

@Testpublic voidtest1(){//求年龄平均值

Double average =list.stream().collect(Collectors.averagingLong(Student::getAge));

}

2.22、collect:collectingAndThen

两步结束,先如何,在如何

@Testpublic voidtest1(){//求年龄平均值

String average = list.stream().collect(Collectors.collectingAndThen(Collectors.averagingInt(Student::getAge), a->"哈哈,平均年龄"+a));

System.out.println(average);

}

结果:

哈哈,平均年龄20.5

2.23、collect:counting

求个数

@Testpublic voidtest1(){//求数量

Long num =list.stream().collect(Collectors.counting());

System.out.println(num);

}

2.24、collect:groupingBy(Function)

接下来所有的都是用下面的新List数据测试使用

public static List list =Arrays.asList(new Student("九天", "男", 5000, 18, "天秤座"),new Student("十夜", "男", 4000, 16, "双鱼座"),new Student("十一郎", "男", 3000, 24, "水瓶座"),new Student("十二郎", "男", 3000, 24, "水瓶座")

);

@Testpublic voidtest1(){

Map> result =list.stream().collect(Collectors.groupingBy(Student::getAge));for(Integer age:result.keySet()){

System.out.println(result.get(age));

}

}

结果:

[Student(name=十夜, sex=男, salary=4000, age=16, star=双鱼座)]

[Student(name=九天, sex=男, salary=5000, age=18, star=天秤座)]

[Student(name=十一郎, sex=男, salary=3000, age=24, star=水瓶座), Student(name=十二郎, sex=男, salary=3000, age=24, star=水瓶座)]

2.25、collect:groupingBy(Function,Collector)

@Testpublic voidtest1(){//先分组,在计算每组的个数

Map num =list.stream().collect(Collectors.groupingBy(Student::getAge,Collectors.counting()));

System.out.println(num);

}

结果:

{16=1, 18=1, 24=2}

2.26、collect:groupingBy(Function, Supplier, Collector)

@Testpublic voidtest1(){//先分组,在计算每组的个数,然后排序

Map num = list.stream().collect(Collectors.groupingBy(Student::getAge, TreeMap::new,Collectors.counting()));

System.out.println(num);

}

2.27、collect:groupingByConcurrent

同上,不过这个Concurrent是并发的,也有3个方法,和上面非并发一个效果

groupingByConcurrent(Function)

groupingByConcurrent(Function, Collector)

groupingByConcurrent(Function, Supplier, Collector)

2.28、collect:joining()

@Testpublic voidtest1(){//名字拼接

String result =list.stream().map(Student::getName).collect(Collectors.joining());

System.out.println(result);

}

结果:

九天十夜十一郎十二郎

2.29、collect:joining(str)

@Testpublic voidtest1(){//名字拼接,用逗号隔开

String result = list.stream().map(Student::getName).collect(Collectors.joining(","));

System.out.println(result);

}

结果:

九天,十夜,十一郎,十二郎

2.30、collect:joining(str, prefix, suffix)

@Testpublic voidtest1(){//名字拼接,包含前缀、后缀

String result = list.stream().map(Student::getName).collect(Collectors.joining(",","hello","world"));

System.out.println(result);

}

结果:

hello九天,十夜,十一郎,十二郎world

2.31、collect:summarizingDouble

@Testpublic voidtest1(){//求年龄的最大值、最小值、平均值、综合以及人数

DoubleSummaryStatistics result =list.stream().collect(Collectors.summarizingDouble(Student::getAge));

System.out.println(result);

}

结果:

DoubleSummaryStatistics{count=4, sum=82.000000, min=16.000000, average=20.500000, max=24.000000}

2.32、collect:toCollection

有很多如

3、Date

3.1、JDK7 Date缺点

1、所有的日期类都是可变的,因此他们都不是线程安全的,这是Java日期类最大的问题之一

2、Java的日期/时间类的定义并不一致,在java.util和java.sql的包中都有日期类,此外用于格式化和解析的类在java.text包中定义

3、java.util.Date同时包含日期和时间,而java.sql.Date仅包含日期,将其纳入java.sql包并不合理。另外这两个类都有相同的名字,这本身就是一个非常糟糕的设计。对于时间、时间戳、格式化以及解析,并没有一些明确定义的类。对于格式化和解析的需求,我们有java.text.DateFormat抽象类,但通常情况下,SimpleDateFormat类被用于此类需求

4、日期类并不提供国际化,没有时区支持,因此Java引入了java.util.Calendar和java.util.TimeZone类,但他们同样存在上述所有的问题

3.2、JDK8 Date优势

1、不变性:新的日期/时间API中,所有的类都是不可变的,这对多线程环境有好处。

2、关注点分离:新的API将人可读的日期时间和机器时间(unix timestamp)明确分离,它为日期(Date)、时间(Time)、日期时间(DateTime)、时间戳(unix timestamp)以及时区定义了不同的类。

3、清晰:在所有的类中,方法都被明确定义用以完成相同的行为。举个例子,要拿到当前实例我们可以使用now()方法,在所有的类中都定义了format()和parse()方法,而不是像以前那样专门有一个独立的类。为了更好的处理问题,所有的类都使用了工厂模式和策略模式,一旦你使用了其中某个类的方法,与其他类协同工作并不困难。

4、实用操作:所有新的日期/时间API类都实现了一系列方法用以完成通用的任务,如:加、减、格式化、解析、从日期/时间中提取单独部分,等等。

5、可扩展性:新的日期/时间API是工作在ISO-8601日历系统上的,但我们也可以将其应用在非IOS的日历上。

3.3、JDK8 Date新增字段

Java.time包中的是类是不可变且线程安全的。新的时间及日期API位于java.time中,java8 time包下关键字段解读。

属性

含义

Instant

代表的是时间戳

LocalDate

代表日期,比如2020-01-14

LocalTime

代表时刻,比如12:59:59

LocalDateTime

代表具体时间 2020-01-12 12:22:26

ZonedDateTime

代表一个包含时区的完整的日期时间,偏移量是以UTC/  格林威治时间为基准的

Period

代表时间段

ZoneOffset

代表时区偏移量,比如:+8:00

Clock

代表时钟,比如获取目前美国纽约的时间

3.4、获取当前时间

Instant instant = Instant.now(); //获取当前时间戳

LocalDate localDate= LocalDate.now(); //获取当前日期

LocalTime localTime= LocalTime.now(); //获取当前时刻

LocalDateTime localDateTime= LocalDateTime.now(); //获取当前具体时间

ZonedDateTime zonedDateTime= ZonedDateTime.now(); //获取带有时区的时间

3.5、字符串转换

jdk8:

String str= "2019-01-11";

DateTimeFormatter formatter= DateTimeFormatter.ofPattern("yyyy-MM-dd");

LocalDate localDate=LocalDate.parse(str, formatter);

jdk7:

SimpleDateFormat simpleDateFormat= new SimpleDateFormat("yyyy-MM-dd");try{

Date date=simpleDateFormat.parse(str);

}catch(ParseException e){

e.printStackTrace();

}

3.6、Date转换LocalDate

importjava.time.Instant;importjava.time.LocalDate;importjava.time.ZoneId;importjava.util.Date;public classTest {public static voidmain(String[] args) {

Date date= newDate();

Instant instant=date.toInstant();

ZoneId zoneId=ZoneId.systemDefault();//atZone()方法返回在指定时区从此Instant生成的ZonedDateTime。

LocalDate localDate =instant.atZone(zoneId).toLocalDate();

System.out.println("Date = " +date);

System.out.println("LocalDate = " +localDate);

}

}

3.7、LocalDate转Date

importjava.time.LocalDate;importjava.time.ZoneId;importjava.time.ZonedDateTime;importjava.util.Date;public classTest {public static voidmain(String[] args) {

ZoneId zoneId=ZoneId.systemDefault();

LocalDate localDate=LocalDate.now();

ZonedDateTime zdt=localDate.atStartOfDay(zoneId);

Date date=Date.from(zdt.toInstant());

System.out.println("LocalDate = " +localDate);

System.out.println("Date = " +date);

}

}

3.8、时间戳转LocalDateTime

long timestamp =System.currentTimeMillis();

Instant instant=Instant.ofEpochMilli(timestamp);

LocalDateTime.ofInstant(instant, ZoneId.systemDefault());

3.9、LocalDateTime转时间戳

LocalDateTime dateTime =LocalDateTime.now();

dateTime.toInstant(ZoneOffset.ofHours(8)).toEpochMilli();

dateTime.toInstant(ZoneOffset.of("+08:00")).toEpochMilli();

dateTime.atZone(ZoneId.systemDefault()).toInstant().toEpochMilli();

3.10、LocalDate方法总结

getYear() int获取当前日期的年份

getMonth() Month 获取当前日期的月份对象

getMonthValue()int获取当前日期是第几月

getDayOfWeek() DayOfWeek 表示该对象表示的日期是星期几

getDayOfMonth()int表示该对象表示的日期是这个月第几天

getDayOfYear()int表示该对象表示的日期是今年第几天

withYear(intyear) LocalDate 修改当前对象的年份

withMonth(intmonth) LocalDate 修改当前对象的月份

withDayOfMonth(intdayOfMonth) LocalDate 修改当前对象在当月的日期

isLeapYear()boolean是否是闰年

lengthOfMonth()int这个月有多少天

lengthOfYear()int该对象表示的年份有多少天(365或者366)

plusYears(longyearsToAdd) LocalDate 当前对象增加指定的年份数

plusMonths(longmonthsToAdd) LocalDate 当前对象增加指定的月份数

plusWeeks(longweeksToAdd) LocalDate 当前对象增加指定的周数

plusDays(longdaysToAdd) LocalDate 当前对象增加指定的天数

minusYears(longyearsToSubtract) LocalDate 当前对象减去指定的年数

minusMonths(longmonthsToSubtract) LocalDate 当前对象减去注定的月数

minusWeeks(longweeksToSubtract) LocalDate 当前对象减去指定的周数

minusDays(longdaysToSubtract) LocalDate 当前对象减去指定的天数

compareTo(ChronoLocalDateother)int比较当前对象和other对象在时间上的大小,返回值如果为正,则当前对象时间较晚,

isBefore(ChronoLocalDateother)boolean比较当前对象日期是否在other对象日期之前

isAfter(ChronoLocalDateother)boolean比较当前对象日期是否在other对象日期之后

isEqual(ChronoLocalDateother)boolean 比较两个日期对象是否相等

原文链接:https://my.oschina.net/mdxlcj/blog/1622718

java 8 详解_java8新特性详解(转载)相关推荐

  1. Java EE 8的五大新特性详解

    Java EE 8的五大新特性详解 2018.4.3 版权声明:本文为博主chszs的原创文章,未经博主允许不得转载. Java EE 8带来了很多新特性,其中最好的新特性有下面五个. 备受期待的Ja ...

  2. java lambda表达式详解_Java8新特性Lambda表达式详解

    课程目标: 通过本课程的学习,详细掌握Java8新特性之Lambda表达式: 适用人群:有Java基础的开发人员: 课程概述:从Java 8出现以来lambda是最重要的特性之一,它可以让我们用简洁流 ...

  3. java lambda表达式详解_Java8新特性:Lambda表达式详解

    在 Java 版本的历次更新迭代中,Java8 是一个特殊的存在,与以往的版本升级不同.我们对 Java8 似乎抱有更大的期待,因为它是 Java5 之后最重要的一次升级,提供了十多个新特性,其中 L ...

  4. java lambda表达式详解_java8新特性-Lambda表达式的详解(从0开始)

    这几天复习了java8的一些新特性,作为一个从java5以来最具革命性的版本,一直没有来得及总结.本系列文章主要是从<java8实战>总结的.这是第一篇文章主要介绍java8的lambda ...

  5. Java | 学习系列 Java1.8 新特性详解( 包含学习代码 )

    前言: Java 8 已经发布很久了,很多报道表明Java 8 是一次重大的版本升级.在Java Code Geeks上已经有很多介绍Java 8新特性的文章,例如Playing with Java ...

  6. java的collect用法_java8新特性:stream流中collect用法

    java8新特性:stream流中collect用法 java8新特性:stream流中collect用法 1.toList List collectList = Stream.of(1, 2, 3, ...

  7. java打印日期序列_Java8新特性之新日期API

    早期的日期 API 在早期也就是 Java 8 之前,JDK 原生比较有名的有两个类: Date 类 Calendar 类 这两个类相对来说用起来是比较困难的,之前我们往往是用的第三方的库. 新日期 ...

  8. java lamdba表达式效率_java8新特性Lambda表达式为什么运行效率低

    Lambda表达式为什么运行效率低 准备 我为什么说Lambda表达式运行效率低. 先准备一个list: 先用Lambda表达式的方式来循环一下这个list: 运行时间大概为110ms 再用普通方式来 ...

  9. java 接口的静态方法_Java8新特性:接口的默认方法与接口的静态方法

    默认方法允许接口方法定义默认实现,子类方法不必须实现此方法而就可以拥有该方法及实现.如下: public interface DefaultFuncInter { int getInt(); defa ...

最新文章

  1. android百度地图更换定位图标,android百度地图定位,改变MyLocationOverlay默认图标(原始为蓝色点)(两种方法)...
  2. php调用txt接口,PHP 如何更优雅地调用 API 接口
  3. 黄金点游戏之客户端(homework-05)
  4. Windows未能启动,原因可能是最近更改了硬件或软件,解决此问题的步骤
  5. Spring中Bean的作用域都有哪些?
  6. Golang笔记——单元测试
  7. java连接mysql实现增删改查_JDBC之Java连接mysql实现增删改查
  8. CC3200在sl_Start函数处不断重启复位的原因解析
  9. python培训价目表-python培训班费用在多少?
  10. Lightroom Classic 教程,如何在 Lightroom 中创建晕影?
  11. BIOS的启动原理学习--加载引导程序
  12. WordPress简约mkBlog博客主题模板v2.1
  13. Math.abs()方法
  14. gls开发_广义最小二乘gls数学推导直觉
  15. Unity3D:2D角色移动篇2:动画的添加
  16. 电脑k歌,电脑K歌软件有哪些 5款热门K软件推荐
  17. html将页面分成四部分,将HTML页面拆分为定义的宽度和高度部分
  18. 数字化时代,基于令牌的身份验证是如何工作?
  19. python第二周day5
  20. Linux下双网卡分配同一网段地址问题分析

热门文章

  1. SecureCRT的安装和使用
  2. 软件需求变更管理七步法
  3. 0 full gc时cpu idle_【cpuidle】计算每个cpu进入idle的时间
  4. android l android 5,关于Android L的5个有趣事实
  5. 微信小程序 input、textarea设置宽度100%,超出父元素的宽度
  6. PyCharm调试程序
  7. 算法的深层次知识是数学,这些常用的互联网经典算法应用案例,你知道几个?
  8. 过去70年人工智能领域 - 最苦涩的教训
  9. Linux系统安装Anaconda3教程
  10. html offsetwidth 字符串宽度,基于js中style.width与offsetWidth的区别(详解)