jdk1.8新特性

一、Lambda表达式

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

lambda表达式本质上是一段匿名内部类,也可以是一段可以传递的代码。

为什么要使用?
lambda是一个匿名函数,我们可以把lambda理解为一个可以传递的代码(将代码像数据一样传递),可以写出更简洁更灵活的代码,增强了代码的可读性。

lambda 的结构

  1.   一个 Lambda 表达式可以有零个或多个参数
    
  2.   参数的类型既可以明确声明,也可以根据上下文来推断。例如:(int a)与(a)效果相同
    
  3.    所有参数需包含在圆括号内,参数之间用逗号相隔。例如:(a, b) 或 (int a, int b) 或 (String a, int b, float c)
    
  4.   空圆括号代表参数集为空。例如:() -> 42
    
  5.   当只有一个参数,且其类型可推导时,圆括号()可省略。例如:a -> return a*a
    
  6.     Lambda 表达式的主体可包含零条或多条语句
    
  7.   如果 Lambda 表达式的主体只有一条语句,花括号{}可省略。匿名函数的返回类型与该主体表达式一致
    
  8.   如果 Lambda 表达式的主体包含一条以上语句,则表达式必须包含在花括号{}中(形成代码块)。匿名函数的返回类型与代码块的返回类型一致,若没有返回则为空
    

在这里插入图片描述

方法引用
若lambda体中的内容有方法已经实现了,那么可以使用“方法引用” ,也可以理解为方法引用是lambda表达式的另外一种表现形式并且其语法比lambda表达式更加简单

(a) 方法引用

三种表现形式:

对象::实例方法名
例如:Consumer con = System.out::println;

类::静态方法名
例如:BiFunction<Integer, Integer, Integer> biFun = Integer::compare;

类::实例方法名 (lambda参数列表中第一个参数是实例方法的调用者,第二个参数是实例方法的参数时可用)
例如:BiFunction<String, String, Boolean> fun = String::equals;

(b)构造器引用

格式:ClassName::new

例如:Function<Integer, Employee> fun = Employee::new;

©数组引用

格式:Type[]::new

例如:Function<Integer, String[]> fun = String[]::new;

 /**
	          * ArraysList
	          */
	         //传统方式
	         Integer[] numArr= {1,6,3,2,4,5,7};
	         
	         List<Integer> list = Arrays.asList(numArr);
	         for (Integer num:numArr){
	             System.out.println("===>"+num);
	         }
	         System.out.println("-----------------------");
	 
	         //lambda方式
           list.forEach((num)->{System.out.println("===>"+num); });

二、Stream流

定义:
流是Java API的新成员,它允许我们以声明性方式处理数据集合(通过查询语句来表达,而不是临时编写一个实现)。就现在来说,我们可以把它们看成遍历数据集的高级迭代器。此外,流还可以透明地并行处理,也就是说我们不用写多线程代码了。

Stream 不是集合元素,它不是数据结构并不保存数据,它是有关算法和计算的,它更像一个高级版本的 Iterator。原始版本的 Iterator,用户只能显式地一个一个遍历元素并对其执行某些操作;高级版本的 Stream,用户只要给出需要对其包含的元素执行什么操作,比如 “过滤掉长度大于 10 的字符串”、“获取每个字符串的首字母”等,Stream 会隐式地在内部进行遍历,做出相应的数据转换。

Stream 就如同一个迭代器(Iterator),单向,不可往复,数据只能遍历一次,遍历过一次后即用尽了,就好比流水从面前流过,一去不复返。而和迭代器又不同的是,Stream 可以并行化操作,迭代器只能命令式地、串行化操作。顾名思义,当使用串行方式去遍历时,每个 item 读完后再读下一个 item。而使用并行去遍历时,数据会被分成多个段,其中每一个都在不同的线程中处理,然后将结果一起输出。Stream 的并行操作依赖于 Java7 中引入的 Fork/Join 框架(JSR166y)来拆分任务和加速处理过程。

对stream的操作可以分为两类,中间操作(intermediate operations)和结束操作(terminal operations):

中间操作总是会惰式执行,调用中间操作只会生成一个标记了该操作的新stream。

  结束操作会触发实际计算,计算发生时会把所有中间操作积攒的操作以pipeline的方式执行,这样可以减少迭代次数。计算完成之后stream就会失效。

Stream操作的三个步骤
创建stream:一个数据源(如:集合、数组),获取一个流

中间操作(过滤、map):一个中间操作链,对数据源的数据进行处理

终止操作:一个终止操作,执行中间操作链,并产生结果

stream的创建:

// 1,校验通过Collection 系列集合提供的stream()或者paralleStream()

List<String> list = new ArrayList<>();

Strean<String> stream1 = list.stream();



// 2.通过Arrays的静态方法stream()获取数组流

String[] str = new String[10];

Stream<String> stream2 = Arrays.stream(str);



// 3.通过Stream类中的静态方法of

Stream<String> stream3 = Stream.of("aa","bb","cc");

Stream的中间操作:

多个中间操作可以连接起来形成一个流水线,除非流水线上触发终止操作,否则中间操作不会执行任何的处理!而在终止操作时一次性全部处理,称为“惰性求值”。

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
Stream的终止操作:

终端操作会从流的流水线生成结果。其结果可以是任何不是流的值,例如:List、Integer,甚至是 void 。

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

三、新的日期API

1.8之前JDK自带的日期处理类非常不方便,我们处理的时候经常是使用的第三方工具包,比如commons-lang包等。不过1.8出现之后这个改观了很多,比如日期时间的创建、比较、调整、格式化、时间间隔等。这些类都在java.time包下。比原来实用了很多。

新的日期API好处:

  • 之前使用的java.util.Date月份从0开始,我们一般会+1使用,很不方便,java.time.LocalDate月份和星期都改成了enum

  • java.util.Date和SimpleDateFormat都不是线程安全的,而LocalDate和LocalTime和最基本的String一样,是不变类型,不但线程安全,而且不能修改。

  • java.util.Date是一个“万能接口”,它包含日期、时间,还有毫秒数,更加明确需求取舍

  • 新接口更好用的原因是考虑到了日期时间的操作,经常发生往前推或往后推几天的情况。用java.util.Date配合Calendar要写好多代码,而且一般的开发人员还不一定能写对

LocalDate/LocalTime/LocalDateTime
  LocalDate为日期处理类、LocalTime为时间处理类、LocalDateTime为日期时间处理类,方法都类似,具体可以看API文档或源码,选取几个代表性的方法做下介绍。

now相关的方法可以获取当前日期或时间,of方法可以创建对应的日期或时间,parse方法可以解析日期或时间,get方法可以获取日期或时间信息,with方法可以设置日期或时间信息,plus或minus方法可以增减日期或时间信息;

TemporalAdjusters
  这个类在日期调整时非常有用,比如得到当月的第一天、最后一天,当年的第一天、最后一天,下一周或前一周的某天等。

DateTimeFormatter
以前日期格式化一般用SimpleDateFormat类,但是不怎么好用,现在1.8引入了DateTimeFormatter类,默认定义了很多常量格式(ISO打头的),在使用的时候一般配合LocalDate/LocalTime/LocalDateTime使用,比如想把当前日期格式化成yyyy-MM-dd hh:mm:ss的形式:

// 当前时间
		LocalDate now = LocalDate.now();
		System.out.println("当前时间:" + now);

		// 前一天时间
		LocalDate yesterday = now.minusDays(1);
		System.out.println("昨天:" + yesterday);
		// 上个月
		LocalDate lastMonth = now.minusMonths(1);
		System.out.println("上个月:" + lastMonth);
		// 上一周
		LocalDate lastWeek = now.minusWeeks(1);
		System.out.println("上一周:" + lastWeek);
		// 一周后
		LocalDate nextWeek = now.plusWeeks(1);
		System.out.println("一周后:" + nextWeek);
		// 指定日期
		LocalDate ofDate = LocalDate.of(2020, 4, 7);
		System.out.println("指定日期:" + ofDate);
		// 转换日期对象
		LocalDate parseDate = LocalDate.parse("2020-04-09");
		System.out.println("转换日期对象:" + parseDate);
		// 取本月第1天:
		LocalDate firstDayOfThisMonth = now.with(TemporalAdjusters.firstDayOfMonth());
		LocalDate firstDayOfThisMonth1 = now.withDayOfMonth(1);
		System.out.println("本月第一天:" + firstDayOfThisMonth);
		System.out.println("本月第一天1:" + firstDayOfThisMonth1);
		// 取本月第2天:
		LocalDate secondDayOfThisMonth = now.withDayOfMonth(2);
		System.out.println("本月第二天:" + secondDayOfThisMonth);
		// 取本月最后一天,再也不用计算是28,29,30还是31:
		LocalDate lastDayOfThisMonth = now.with(TemporalAdjusters.lastDayOfMonth());
		System.out.println("本月最后一天:" + lastDayOfThisMonth);
		// 获取当前月份,得到结果不用加1
		int month = now.getMonthValue();
		System.out.println("当前月份:" + month);
		int dayOfYear = now.getDayOfYear();
		System.out.println("2020年已经度过的天数:" + dayOfYear);
		LocalDateTime nowTime = LocalDateTime.now();
		String formatDate = DateTimeFormatter.ISO_LOCAL_DATE.format(nowTime);
		System.out.println("formatDate:" + formatDate);
		DateTimeFormatter formatter = DateTimeFormatter.ofPattern("YYYY-MM-dd HH:mm:ss");
		String formatDateTime = formatter.format(nowTime);
		System.out.println("formatDateTime:" + formatDateTime);
		DateTimeFormatter formatter1 = DateTimeFormatter.ofPattern("YYYY/MM/dd HH:mm:ss");
		String formatDateTime1 = formatter1.format(nowTime);
		System.out.println("formatDateTime1:" + formatDateTime1);

运行结果:
在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值