文章目录

  • java 8
  • interface
  • 函数式接口
  • Lambda 表达式
  • Stream
  • Optional
  • Date-Time API


java 8

interface

可以有静态方法默认方法

default 修饰的方法,是普通实例方法,可以用this调用,可以被子类继承、重写。
static 修饰的方法,使用上和一般类静态方法一样。但它不能被子类继承,只能用Interface调用。
public interface InterfaceNew {
    static void sm() {
        System.out.println("interface提供的方式实现");
    }
    static void sm2() {
        System.out.println("interface提供的方式实现");
    }

    default void def() {
        System.out.println("interface default方法");
    }
    default void def2() {
        System.out.println("interface default2方法");
    }
    //须要实现类重写
    void f();
}

public interface InterfaceNew1 {
    default void def() {
        System.out.println("InterfaceNew1 default方法");
    }
}
在 Java 8 ,接口和抽象类有什么区别的


1. 接口多实现,类单继承
2. 接口的方法是 public abstract 修饰,变量是 public static final 修饰。 abstract class 可以用其他修饰符
3. interface 的方法是更像是一个扩展插件。而 abstract class 的方法是要继承的。

函数式接口

也称 SAM 接口,即 Single Abstract Method interfaces,有且只有一个抽象方法,但可以有多个非抽象方法的接口。

java.util.function  包下的所有接口都有 @FunctionalInterface 注解,提供函数式编程
只要符合函数式接口的定义就是函数式接口,与是否有

@FunctionalInterface注解无关,注解只是在编译时起到强制规范定义的作用

Lambda 表达式

(parameters) -> expression 或
(parameters) ->{ statements; }
方法的引用  

允许使用 :: 关键字来传递方法或者构造函数引用
表达式返回的类型必须是 functional-interface。
void show() {
   //1.调用静态函数,返回类型必须是functional-interface
    LambdaInterface t = LambdaClass::staticF;

    //2.实例方法调用
    LambdaClass lambdaClass = new LambdaClass();
    LambdaInterface lambdaInterface = lambdaClass::f;

    //3.超类上的方法调用
    LambdaInterface superf = super::sf;

    //4. 构造方法调用
    LambdaInterface tt = LambdaClassSuper::new;
}
Runnable 接口

new Thread(new Runnable() {
            @Override
            public void run() {
                System.out.println("The runable now is using!");
            }
}).start();
//用lambda
new Thread(() -> System.out.println("It's a lambda function!")).start();
Comparator 接口

List<Integer> strings = Arrays.asList(1, 2, 3);

Collections.sort(strings, new Comparator<Integer>() {
@Override
public int compare(Integer o1, Integer o2) {
    return o1 - o2;}
});

//Lambda
Collections.sort(strings, (Integer o1, Integer o2) -> o1 - o2);
//分解开
Comparator<Integer> comperator = (Integer o1, Integer o2) -> o1 - o2;
Collections.sort(strings, comperator);

Stream

java.util.stream

不存储数据,不同的是它可以检索(Retrieve)和逻辑处理集合数据、包括筛选、排序、统计、计数等。可以想象成是 Sql 语句。

它的源数据可以是 Collection、Array 等。由于它的方法参数都是函数式接口类型,所以一般和 Lambda 配合使用

流类型

stream 串行流
parallelStream 并行流,可多线程执行
通过简单的链式编程,使得它可以方便地对遍历处理后的数据进行再处理。
方法参数都是函数式接口类型

一个 Stream 只能操作一次,操作完就关闭了,继续使用这个 stream 会报错。
Stream 不保存数据,不改变数据源

Optional

防止 NPE,是程序员的基本修养,注意 NPE 产生的场景

1) 返回类型为基本数据类型,return 包装数据类型的对象时,自动拆箱有可能产生 NPE。
反例:public int f() { return Integer 对象}, 如果为 null,自动解箱抛 NPE。

2) 数据库的查询结果可能为 null。

3) 集合里的元素即使 isNotEmpty,取出的数据元素也可能为 null。

4) 远程调用返回对象时,一律要求进行空指针判断,防止 NPE

5) 对于 Session 中获取的数据,建议进行 NPE 检查,避免空指针。

6) 级联调用 obj.getA().getB().getC();一连串调用,易产生 NPE。

正例:使用 JDK8 的 Optional 类来防止 NPE 问题。
建议使用 Optional 解决 NPE(java.lang.NullPointerException)问题,它就是为 NPE 而生的
其中可以包含空值或非空值
Zoo zoo = getZoo();
if(zoo != null){
   Dog dog = zoo.getDog();
   if(dog != null){
      int age = dog.getAge();
      System.out.println(age);
   }
}

Optional.ofNullable(zoo).map(o -> o.getDog()).map(d -> d.getAge()).ifPresent(age ->
    System.out.println(age)
);
ofNullable 方法和of方法唯一区别就是当 value 为 null 时
ofNullable 返回的是EMPTY,of 会抛出 NullPointerException 异常
如果需要把 NullPointerException 暴漏出来就用 of,否则就用 ofNullable
如果坚决不想看见 NPE,就不要用 of() 、 get() 、flatMap(..)

Date-Time API

java.util.Date 既包含日期又包含时间,而 java.time 把它们进行了分离
LocalDateTime.class //日期+时间 format: yyyy-MM-ddTHH:mm:ss.SSS
LocalDate.class //日期 format: yyyy-MM-dd
LocalTime.class //时间 format: HH:mm:ss
Java 8 之前 转换都需要借助 SimpleDateFormat 类
而Java 8 之后只需要 LocalDate、LocalTime、LocalDateTime的 of 或 parse 方法