Java 8 新特性

Java 8

Java 8(JDK 1.8),发布于 2014 年 03 月 18 日。

  • Java 语言开发的一个主要版本。

  • Java 8 包含语言、编译器、库、工具、JVM 等方面的新特性。

    image-20220516002839898

1、语言

1.1、Lambda 表达式(❗)

允许函数作为方法参数传递

简化了匿名内部类的复杂写法。

1.1.1、语法

  • 函数式接口:仅有一个抽象方法的接口(下一节详解)

  • ->箭头操作符,将 lambda 表达式分为两部分。

  • 左边是形参列表 ()

  • 右边是方法体 {}

    <函数式接口> <变量名> = (形参列表) -> {
        // 方法体
    };
    

1.1.2、case:简化过程

① Runnable

Java 线程创建 的方式之一

无需传参

  1. 匿名内部类

    Runnable r1 = new Runnable() {
        @Override
        public void run() {
            System.out.println("running-1");
        }
    };
    new Thread(r1).start();
    
  2. Lambda 表达式:省略 new方法名 之间的内容。

    Runnable r2 = () -> {
        System.out.println("running-2");
    };
    new Thread(r2).start();
    

② Comparator

通常用于定义 集合 元素的比较规则

需传参

  1. 匿名内部类

    Comparator<String> c1 = new Comparator<String>() {
        @Override
        public int compare(String o1, String o2) {
            return o1.length() - o2.length();
        }
    };
    TreeSet<String> set1 = new TreeSet<>(c1);
    
  2. Lambda 表达式:省略以下内容

    • new方法名 之间的内容。

    • 方法参数类型。

      Comparator<String> c2 = (o1, o2) -> {
          return o1.length() - o2.length();
      };
      TreeSet<String> set2 = new TreeSet<>(c2);
      

1.1.3、说明

  • Lambda 表达式不会生成单独的内部类文件
  • 形参列表
    1. 形参列表为空,保留 ()
    2. 数据类型会自动推断,可省略。
    3. 形参只有 1 个,可省略 ()
  • 方法体
    • 仅 1 条语句,无返回值时可省略 {}
    • 仅 1 条语句,有返回值时可省略 {},需同时省略 return

1.2、函数式接口

函数式接口:有且仅有一个抽象方法的接口。

  • 可使用 Lambda 表达式,Lambda 表达式会匹配该抽象方法。
  • @Functionallnterface 注解:检测接口是否符合函数式接口。

常见函数式接口

方法 入参 → 出参 说明
Consumer<T> void accpet(T t) T → void 消费一个值
Supplier<T> T get() 无 → T 提供一个值
Function<T, R> R apply(T t) T → R 运算
Predicate<T> boolean test(T t) T → boolean 判断是否符合条件

1.3、方法引用(❗)

Lambda 表达式的简写形式

使用场景:Lambda 表达式的方法体中,调用一个特定的已经存在的方法。

1.3.1、常见形式

操作符 方法
对象 :: 实例方法
:: 静态方法
:: 实例方法
:: new

1.3.2、示例

  • 对象 :: 实例方法

    Consumer<String> c = s -> System.out.println(s);
    // 简化
    Consumer<String> c = System.out::println;
    
  • :: 静态方法

    Comparator<Integer> c = (o1, o2) -> Integer.compare(o1, o2);
    // 简化
    Comparator<Integer> c = Integer::compare;
    
  • :: 实例方法

    // 假设有 Employee 类
    Function<Employee, String> fx = e -> e.getName();
    // 简化
    Function<Employee, String> fx = Employee::getName;
    
  • :: new

    Supplier<Employee> s = () -> new Employee();
    // 简化
    Supplier<Employee> s = Employee::new;
    

2、工具

2.1、Stream 流式编程

Stream(流)定义了对集合/数组的操作

  • 包名:package java.util.stream

  • 特点

    • Stream 本身不存储元素(数据),元素存储在集合/数组中。
    • Stream 不会改变源对象,每次操作时返回一个新 Stream。
    • Stream 的中间操作是延迟执行的,在终止操作时执行。
  • 说明

    • 相比 I/O 流 操作磁盘,Stream 是操作集合/数组

    • Stream 可理解为流水线,允许多个操作(链式调用)。

      image-20220516104617549

使用步骤

  • 创建 Stream
  • 中间操作:将初始 Stream 处理转换为新的 Stream,延迟执行。
  • 终止操作:产生预期的结果。

2.1.1、创建 Stream

方法 说明
Collection 对象 stream()parallelStream() 串行/并行
Arrays 工具类 stream()
Stream 接口 of()iterate() generate() 构建/迭代/生成
IntStream、LongStream、DoubleStream 接口 of()range()rangeClosed() 构建/前闭后开/前闭后闭

2.1.2、中间操作(❗)

含义 参数 备注
filter 过滤 Predicate
limit 限制个数 long 只处理集合前 n 个元素
skip 跳过个数 long 跳过集合前 n 个元素
distinct 去重 - 需重写 hashCode() 和 equals()
sorted 排序 - 升序

map:映射为另一个流

  • 参数:Function

  • 示例:从 User 集合映射为 username 集合。

    // List<User> userList;
    userList.stream()
        .map(u - u.getName());
    

parallel:转换成并行流

// 判断是否并行流
list.stream().isParallel();
// 转换成并行流
list.stream().parallel();

2.1.3、终止操作(❗)

含义 参数 说明
forEach 遍历 Consumer
min 最小值 Comparator 返回 Optional,通过 get() 获取结果
max 最大值 Comparator 返回 Optional,通过 get() 获取结果
count 计数 - 返回 long

  • reduce:约简

    • 参数:BinaryOperator

    • 示例:求和

      Integer[] arr = {100, 100, 200, 300, 300, 400, 500, 10};
      List<Integer> list = Arrays.asList(arr);
      
      Optional<Integer> reduce = list.stream()
          .reduce((a, b) -> a + b);
      reduce.get();
      
  • collect:将流转换成集合。

    • 参数:Collector

    • 示例:通过 User 集合的流获取 username 流,再转换成集合。

      // List<User> userList
      userList.stream()
          // User流 -> username流
          .map(User::getName)
          // username流 -> 集合
          .collect(Collectors.toList());
      

2.2、新时间 API

旧时间 API 设计混乱,存在线程安全问题。

JDK 8 引入新时间 API(package java.time)

2.2.1、本地化日期时间

  • 类型
    • LocalDate
    • LocalTime
    • LocalDateTime
  • 创建方式
    • now()
    • of()
  • 操作
    • 获取时间:getYear(),getMonthValue(),...
    • 修改时间:plusXxx(),minusXxx(),...

2.2.2、时间戳 & 时区

  • lnstant:时间戳

    • 创建方式:now(),of()
    • 修改时间:plusXxx(),minusXxx(),...
  • Zoneld:时区

    // 本机支持时区
    ZoneId.getZone.getAvailableZoneIds();
    // 本机默认时区
    ZoneId.systemDefault();
    
  • 日期转换

    • Date → Instance → LocalDateTime

      // Date -> Instance
      date.toInstant();
      // Instance -> LocalDateTime
      LocalDateTime.ofInstance(Instance i, ZoneId zid);
      
    • 反之

      // LocalDateTime -> Instance:需指定时区
      localDateTime.atZone(ZoneId).toInstant();
      // Instance -> Date
      Date.from(Instance i);
      

2.2.3、格式化类

  • SimpleDateFormatter:线程不安全。

  • DateTimeFormatter:线程安全。

    // 创建
    DateTimeFormatter dtf = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
    // 时间 -> 字符串
    dtf.format(LocalDateTime.now());
    // 字符串 -> 时间
    LocalDateTime.parse("时间字符串", dtf);
    

2.3、Optional

👉 Optional 判空新姿势

posted @ 2022-05-04 23:52  Jaywee  阅读(32)  评论(0编辑  收藏  举报

👇