在接口中新增了default方法和static方法,这两种方法可以有方法体
接口中的static方法不能被继承,也不能被实现类调用,只能被自身调用
示例代码:
static void staticMethod(){
    System.out.println("staticMethod方法");
}default方法可以被子接口继承也可被实现类调用
default void defaultMethod(){
    System.out.println("defaultMethod方法");
}//实现类调用
public static void main(String[] args) {
    Test test = new Test();
    test.defaultMethod();	//调用default方法
}default方法被继承时,可以被子接口覆写
//子接口覆写
public interface TestNewInterfaceExtend extends TestNewInterface{
    @Override
    default void defaultMethod() {
        
    }
}如果一个类实现了多个接口 且这些接口中无继承关系, 这些接口中若有相同的(同名,同参数)的default方法,则接口实现类会报错, 接口实现类必须通过特殊语法指定该实现类要实现那个接口的default方法 特殊语法:<接口>.super.<方法名>([参数])
TestNewInterface.super.defaultMethod();Lambda表达式可以看成是匿名内部类,使用Lambda表达式时,接口必须是函数式接口
<函数式接口>  <变量名> = (参数1,参数2...) -> {
	//方法体
}说明:
(参数1,参数2…)表示参数列表;->表示连接符;{}内部是方法体 1、=右边的类型会根据左边的函数式接口类型自动推断; 2、如果形参列表为空,只需保留(); 3、如果形参只有1个,()可以省略,只需要参数的名称即可; 4、如果执行语句只有1句,且无返回值,{}可以省略,若有返回值,则若想省去{},则必须同时省略return,且执行语句也保证只有1句; 5、形参列表的数据类型会自动推断; 6、lambda不会生成一个单独的内部类文件; 7、lambda表达式若访问了局部变量,则局部变量必须是final的,若是局部变量没有加final关键字,系统会自动添加,此后在修改该局部变量,会报错;
语法:
<函数式接口>  <变量名> = <实例>::<实例方法名>
//调用
<变量名>.接口方法([实际参数...])LambdaTest lt1 = s-> System.out.println(s);
lt1.print("原方式");
        
//改写为:
LambdaTest lt2 = System.out::println;
lt2.print("实例引用方式");将lt2调用时的实际参数传递给了PrintStream类中的println方法,并调用该方法
语法:
<函数式接口>  <变量名> = <类>::<类方法名称>
//调用
<变量名>.接口方法([实际参数...])现有数组list,要给其排序:
LambdaTest lt = Collections::sort;
lt.sort(list, (a,b) -> {
    return a-b;
});后面的(a,b)是Comparator接口的lambda表达式写法
定义、调用接口时,需要多传递一个参数,并且参数的类型与引用实例的类型一致 语法:
//定义接口
interface <函数式接口>{
    <返回值> <方法名>(<类><类名称>,[其他参数...]); 
}
<函数式接口>  <变量名> = <类>::<类实例方法名>
//调用
<变量名>.接口方法(类的实例,[实际参数...])将调用方法时的传递的实际参数,从第二个参数开始(第一个参数指定的类的实例),全部传递给引用的方法,执行引用的方法;
把方法的所有参数全部传递给引用的构造器,根据参数类型自动推断调用的构造器方法;
语法:
<函数式接口>  <变量名> = <类>::<new>
//调用
<变量名>.接口方法([实际参数...])根据传入的参数类型,自动匹配构造函数
如果一个接口只有一个抽象方法,则该接口称之为函数式接口,默认方法不算抽象方法
 函数式接口可以使用Lambda表达式,lambda表达式会被匹配到这个抽象方法上
@FunctionalInterface 注解,这个接口多于一个抽象方法的时候会报错的
示例代码:
@FunctionalInterface
interface MyFuncInterface<F, T> {
    T myMethod(F f);
}在lambda表达式中访问外层作用域和老版本的匿名对象中的方式很相似。你可以直接访问标记了final的外层局部变量,或者实例的字段以及静态变量。

public static void main(String[] args) {
    //Function<String, String> function = new Function<String, String>() {
    //    @Override
    //    public String apply(String s) {
    //        return s;
    //    }
    //};
    Function<String, String> function = (s)->{
        return s;
    };
    System.out.println(function.apply("AAA"));
}
public static void main(String[] args) {
    //    Predicate<String> predicate = new Predicate<String>() {
    //        @Override
    //        public boolean test(String s) {
    //            return s.equals("AAA");
    //        }
    //    };
    Predicate<String> predicate = (s)->{
        return s.equals("AAA");
    };
    System.out.println(predicate.test("AAA"));
}
public static void main(String[] args) {
//    Consumer<String> consumer = new Consumer<String>() {
//        @Override
//        public void accept(String s) {
//            System.out.println(s);
//        }
//    };
    Consumer<String> consumer = (s) ->{
        System.out.println(s);
    };
    consumer.accept("AAA");
}
public static void main(String[] args) {
//    Supplier<String> supplier = new Supplier<String>() {
//        @Override
//        public String get() {
//            return "AAA";
//        }
//    };
    Supplier<String> supplier = ()->{
        return "AAA";
    };
    System.out.println(supplier.get());
}Stream 不是集合元素,它不是数据结构并不保存数据,它是有关算法和计算的,它更像一个高级版本的Iterator。
// 1、of创建
Stream stream = Stream.of("a", "b", "c");
// 2、Arrays
String[] strArray = new String[]{"a", "b", "c"};
stream = Stream.of(strArray);
stream = Arrays.stream(strArray);
// 3、Collections
List<String> list = Arrays.asList(strArray);
stream = list.stream();
stream.forEach(System.out::println);对于基本数值型,目前有三种对应的包装类型 Stream:IntStream、LongStream、DoubleStream。
// 3、流转换为其他数据结构
Stream<String> stream1 = Stream.of(new String[]{"1", "2", "3"});
//        List<String> list1 = stream1.collect(Collectors.toList());
//        List<String> list2 = stream1.collect(Collectors.toCollection(ArrayList::new));
// 一个 Stream 只可以使用一次
String str = stream1.collect(Collectors.joining());
System.out.println(str);Java 8通过发布新的Date-Time API (JSR 310)来进一步加强对日期与时间的处理。对日期与时间的操作一直是Java程序员最痛苦的地方之一。标准的 java.util.Date以及后来的java.util.Calendar一点没有改善这种情况(可以这么说,它们一定程度上更加复杂)。 这种情况直接导致了Joda-Time——一个可替换标准日期/时间处理且功能非常强大的Java API的诞生。Java 8新的Date-Time API (JSR 310)在很大程度上受到Joda-Time的影响,并且吸取了其精髓。
LocalDate date = LocalDate.now(); // 当前日期
date = date.plusDays(1); // 增加一天
date = date.plusMonths(1); // 增加一个月
System.out.println(date);
date = date.minusDays(1); // 减少一天
date = date.minusMonths(1); // 减少一个月
System.out.println(date);
/*
结果如下:
================
2020-08-23
2020-07-22
================
*/LocalTime time = LocalTime.now(); // 当前时间
time = time.plusHours(1);// 增加一小时
time = time.plusMinutes(1); // 增加一分钟
time = time.plusSeconds(1); // 增加一秒
System.out.println(time);
time = time.minusHours(1);  //减小一小时
time = time.minusMinutes(1); // 减少一分钟
time = time.minusSeconds(1); // 减少一秒
System.out.println(time);
/*
结果如下:
================
22:27:55.349
21:26:54.349
================
*/LocalDateTime localDateTime = LocalDateTime.now();
System.out.println(localDateTime); // UTC格式
System.out.println(
    localDateTime.format(
        DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")
    )
); // 自定义格式
/*
结果如下:
================
2020-07-22T21:29:03.781
2020-07-22 21:29:03
================
*/ZonedDateTime zonedDateTime = ZonedDateTime.now();
System.out.println(zonedDateTime);
ZonedDateTime zonedDatetimeFromZone = ZonedDateTime.now(ZoneId.of("America/Los_Angeles"));
System.out.println(zonedDatetimeFromZone);
ZoneId zoneId = ZoneId.systemDefault();
System.out.println(zoneId);
/*
结果如下:
================
2020-07-22T21:37:26.233+08:00[Asia/Shanghai]
2020-07-22T06:37:26.235-07:00[America/Los_Angeles]
Asia/Shanghai
================
*///它通过指定一个时区,然后就可以获取到当前的时刻,日期与时间。
// Clock可以替换System.currentTimeMillis()与TimeZone.getDefault()
Clock utc = Clock.systemUTC(); // 世界标准时间
System.out.println(LocalDateTime.now(utc));
Clock shanghai = Clock.system(ZoneId.of("Asia/Shanghai")); // 上海时间
System.out.println(LocalDateTime.now(shanghai));
/*
结果如下:
================
2020-07-22T13:32:17.832
2020-07-22T21:32:17.895
================
*/计算两个日期之间差的天数
LocalDateTime from = LocalDateTime.parse("2020-07-21 20:35:50", DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
LocalDateTime to = LocalDateTime.parse("2020-07-22 21:35:50", DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
Duration duration = Duration.between(from, to);
System.out.println("Duration in days: " + duration.toDays());
System.out.println("Duration in hours: " + duration.toHours());在Java 8中支持多重注解了