JDK 8 特性

发布时间 2023-03-27 15:15:08作者: 之士咖啡

Lambda表达式

本质上是一段匿名内部类 ,功效:减少无用的代码,以最简单的方式呈现。()、-、>、{ } 以上为 表达式

函数式接口

@FunctionInterface,要求,接口中只有一个抽象方法,且加上此注解。

Consumer 《T》:消费型接口,有参无返回值

	@Test
    public void test(){
        changeStr("hello",(str) -> System.out.println(str));
    }

    /**
     *  Consumer<T> 消费型接口
     * @param str
     * @param con
     */
    public void changeStr(String str, Consumer<String> con){
        con.accept(str);
    }

Supplier 《T》:供给型接口,无参有返回值

@Test
   public void test2(){
       String value = getValue(() -> "hello");
       System.out.println(value);
   }

   /**
    *  Supplier<T> 供给型接口
    * @param sup
    * @return
    */
   public String getValue(Supplier<String> sup){
       return sup.get();
   }

Function 《T,R》::函数式接口,有参有返回值

 	@Test
    public void test3(){
        Long result = changeNum(100L, (x) -> x + 200L);
        System.out.println(result);
    }

    /**
     *  Function<T,R> 函数式接口
     * @param num
     * @param fun
     * @return
     */
    public Long changeNum(Long num, Function<Long, Long> fun){
        return fun.apply(num);
    }

Predicate《T》: 断言型接口,有参有返回值,返回值是boolean类型

	public void test4(){
        boolean result = changeBoolean("hello", (str) -> str.length() > 5);
        System.out.println(result);
    }

    /**
     *  Predicate<T> 断言型接口
     * @param str
     * @param pre
     * @return
     */
    public boolean changeBoolean(String str, Predicate<String> pre){
        return pre.test(str);
    }

Stream API()

使用流程:

  • 创建stream
  • 中间操作(过滤、map)
  • 终止操作

创建:

    // 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");

    // 4.创建无限流
    // 迭代
    Stream<Integer> stream4 = Stream.iterate(0,(x) -> x+2);

    //生成
    Stream.generate(() ->Math.random());

中间操作:

  /**
   * 筛选 过滤  去重
   */
  emps.stream()
          .filter(e -> e.getAge() > 10)
          .limit(4)
          .skip(4)
          // 需要流中的元素重写hashCode和equals方法
          .distinct()
          .forEach(System.out::println);

  /**
   *  生成新的流 通过map映射
   */
  emps.stream()
          .map((e) -> e.getAge())
          .forEach(System.out::println);

  /**
   *  自然排序  定制排序
   */
  emps.stream()
          .sorted((e1 ,e2) -> {
              if (e1.getAge().equals(e2.getAge())){
                  return e1.getName().compareTo(e2.getName());
              } else{
                  return e1.getAge().compareTo(e2.getAge());
              }
          })
          .forEach(System.out::println);

Stream的终止操作:

/**
         *      查找和匹配
         *          allMatch-检查是否匹配所有元素
         *          anyMatch-检查是否至少匹配一个元素
         *          noneMatch-检查是否没有匹配所有元素
         *          findFirst-返回第一个元素
         *          findAny-返回当前流中的任意元素
         *          count-返回流中元素的总个数
         *          max-返回流中最大值
         *          min-返回流中最小值
         */

Optional<Employee> opt = emps.stream().findFirst();

//Convert a Stream to List
List<String> result = emps.stream().collect(Collectors.toList());

实例:

// 将list 分组,然后取每个list 中最大的一个数据
Map<String, VSiFinDirectEntity> latestStations = vSiFinHldDirectEntityList.parallelStream().collect(Collectors.toMap(VSiFinDirectEntity::getCenterCode, entity -> entity, (c1, c2) -> c1.getBeginDatetime().compareTo(c2.getBeginDatetime())> 0 ? c1 : c2));
vSiFinHldDirectEntityList = (List<VSiFinDirectEntity>) latestStations.values();

设计层面上:
抽象类是对事物的抽象,包括事物的属性方法在内,而接口是对行为的抽象仅限于 事物的行为。
抽象类是“是不是”的关系,而接口是“有没有”的关系

接口中的默认方法和静态方法

  1. 接口的默认方法与静态方法都可以写多个
public interface Interface {
    default String getName() {
        return "测试";
    }

    default String getAge() {
        return "18";
    }

    static String getName2(){
        return "zhangsan";
    }
}

为什么要添加静态方法与默认方法 ? -> 为了接口的演化

  • 默认方法:方便在进行进行早期代码合并时,处理兼容性问题,不用破坏原有的代码实现。
  • 静态方法:方便进行将方法与接口进行绑定。如果方法实现上需要静态方法,其静态方法存放用接口中,比放在工具类中更合适

新时间日期API

说明 实例
Instant 瞬时实例 Instant.now() -> 2014-01-14T08:33:33.379Z
LocalDate 本地日期,不包含具体时间 LocalDate.now() -> 2014-01-14
LocalTime 本地时间,不包含日期 LocalTime.now() -> 16:33:33.369(格式:hh:mm:ss:nnn)
LocalDateTime 组合了日期和时间,但不包含时差和时区信息 LocalDateTime.now() -> DateTimeFormatter format = DateTimeFormatter.ofPattern("yyyy-MMM-dd hh:mm:ss") -> arrivalDate.format(format) -> 日期(yyyy-MMM-dd hh:mm:ss)
ZonedDateTime 最完整的日期时间,包含时区和相对UTC或格林威治的时差
YearMonth 组合类,用于表示信用卡到期日、FD到期日、期货期权到期日等。还可以用这个类得到 当月共有多少天,YearMonth实例的lengthOfMonth()方法可以返回当月的天数,在判断2月有28天还是29天时非常有用。
MonthDay 类组合了月份和日,去掉了年,这意味着你可以用它判断每年都会发生事件

参考文章:https://blog.csdn.net/qq_40366738/article/details/106222929