liujijiang

java8 Lambda,Stream,LocalDateTime,Optional

2020.04.20

Lambda

lambda(匿名函数):没有函数名,有时候可能没有参数和返回值

Lambda语法

  • ()-> expression
  • ()-> {statements;}

如果一个参数()可以省去,如果只有一个表达式{}和return可以省去

函数接口

java8很多接口已经声明为函数接口了
比如:

  • Runnable
  • Callable
  • Comparator

三种接口的函数式写法

使用@FunctionInterface定义一个函数式接口

package com.streamTest;

@FunctionalInterface
public interface Person {

    void speak();

}

public static void main(String[] args){

        Person person = () -> System.out.println("123");
        person.speak();
    }

Stream

简介

java8的Stream是对数据集合操作的增强

Stream不是数据结构,不提供存储对象,只是对集合提供一种聚合操作,类似于迭代

跟迭代器一样只能单向处理,提供并行计算模式,充分发挥多核CPU

流程

数据源 -> 数据迭代处理 -> 结果处理

数据源获取方式

  • Collection.stream:从集合中获取
  • Collection.parallelStream:从集合中获取并行流
  • Arrays.stream和Stream.of:从数组中获取
  • BufferedReader.lines:从输入流中获取
  • IntStream.of:从静态方法中获取
  • Stream.generate:自己生成流

数据处理(中间操作)

中间操作返回的是一个新的stream

属于数据处理阶段的操作是:

  • map:映射,把每个对象从一种形式变成另一种形式
  • filter:过滤器,把不符合条件的过滤掉
  • distinct:去重
  • sorted:排序
  • peek
  • limit:只要流的前几个
  • skip:跳过流的前几个
  • parallel
  • sequential
  • unordered

收集结果

stream的最后一步,这之后流彻底用尽

属于最后一步的操作有:

  • forEach:遍历stream
  • forEachOrdered
  • toArray
  • reduce
  • collect:收集流中的每一个对象,然后整体转成其他的数据结构或者数组
  • min
  • max
  • count
  • anyMatch
  • allMatch
  • noneMatch
  • findFirst:返回第一个对象Optional
  • findAny
  • iterator

使用stream后一定要调用close关闭

stream的使用

流的方法分两种

  • 延迟方法:返回值类型仍然是Stream接口自身类型的方法,因此支持链式调用。(除了终结方法外,其余方法均为延迟方法。)
  • 终结方法:返回值类型不再是stream接口自身类型的方法,因此不再支持类似stringBuilder那样的链式调用。本小节中,终结方法包括 count和forEach方法。
  • .filter: 过滤,true的接受,false的过滤
  • forEash: 遍历
  • limit:限制个数
  • skip:跳过前几个

list -> map

LocalDateTime

时间介绍
LocalDateTime最高精确到纳秒
LocalDate最高精确到天
DateTimeFormatter时间格式化
Zoneld设置时区
public static void main(String[] args)  {

        LocalDateTime localDateTime = LocalDateTime.now();

        String time = localDateTime.format(DateTimeFormatter.ofPattern("YY-MM-dd hh:mm:ss"));

        System.out.println(time);
    }

当前时间以及格式化

加减时间

LocalDateTime now = LocalDateTime.now();

        System.out.println(now.plusDays(1));
        System.out.println(now.plusHours(1));
	System.out.println(now.minusDays(2));
        System.out.println(now.withYear(2021));
        System.out.println(now.withDayOfMonth(10));

对天,小时进行加减
直接设置年,天

LocalDateTime和Date相互转换

Date转LocalDateTime

Date now = new Date();

        LocalDateTime localDateTime = LocalDateTime.ofInstant(now.toInstant(), ZoneId.systemDefault());

        System.out.println(now);

        System.out.println(localDateTime);

LocalDateTime转Date

LocalDateTime now = LocalDateTime.now();

        Date date = Date.from(now.atZone(ZoneId.systemDefault()).toInstant());

        System.out.println(date);

Optional

缓解空指针异常

三种创建方法

public static void main(String[] args)  {

        Optional<String> optional1 = Optional.of("123"),
                optional2 = Optional.empty(),
                optional3 = Optional.ofNullable("");
    }

of:不能为空
empty:空对象
ofNullable:可以为空

检测对象是否为空

isPresent:检测对象是否为空

获取值

get:如果为空,抛出异常

空时可以给默认值

orLise:如果对象为null,赋予其一个默认值

public static void main(String[] args)  {

        Optional<String> optional = Optional.empty();

        System.out.println(optional);

        System.out.println(optional.orElse("123"));
    }

Optional为null时抛出异常

orElseThrow:对象为空的时候抛出异常

public static void main(String[] args) throws Exception {

        Optional<String> optional = Optional.empty();

        System.out.println(optional.orElseThrow(() -> new Exception("Optional is empty")));
    }

配合函数接口

三个函数接口:map,filter,flatMap

public static void main(String[] args) throws Exception {

        Optional<String> optional = Optional.of("123");

        System.out.println(optional.filter(it -> it.isEmpty()).orElse("321"));

        System.out.println(optional.map(it -> "hello " + it + " !"));
    }

使用函数接口进行过滤或者映射