一、接口的默认方法
java8以后允许接口设置非抽象方法,本质上相当于实现了一个匿名内部类,用于调用重写的接口方法。
public interface Hehe {
default void hehe() {
System.out.println("hehe");
}
}
二、lamda表达式
要使用一个接口的方法,必须用一个实现他的类,匿名类,或lamda表达式。
lamda表达式本质上是一个匿名方法。允许把函数作为一个方法的参数(函数作为参数传递进方法中)
eg:
普通方法:
public interface Hehe {
default void hehe() {
System.out.println("hehe");
}
}
public int add(int x, int y) {
return x + y;
}
lamda表达式写法:
(int x, int y) -> x + y;
lamda表达式主要用于函数式接口中,用于替换常用的匿名类。
函数式接口:一般标有@FunctionalInterface注解(可有可无),接口中只有一个显式方法的接口,如Comparator接口。
eg:
接口:
@FunctionalInterface
public interface Hehe {
void haha();
}
普通方法实现匿名类:
Hehe h2 = new Hehe() {
@Override
public void haha() {
System.out.println("hehe2");
}
};
lamda方法:
Hehe h1 = () ->{
System.out.println("hehe1");
};
作用域:
lamda表达式不能修改{}外的变量,但是可以访问引用外部变量。
int a =1;
Hehe h1 = (j) ->{
System.out.println(a);
System.out.println("hehe1");
};
三、方法引用
java8 允许使用 :: 来对方法,静态方法,构造函数进行引用。
一个函数式接口的方法使用,如上文所说,可以用匿名类,lamda表达式。也可以使用::对已存在的方法进行引用。
eg:
接口:
@FunctionalInterface
public interface Hehe {
void haha(int a, int b);
}
已存在的方法:
static int lele(int a, int b) {
System.out.println("ll");
return 1;
}
测试:
Hehe hehe = A::lele;
如此,我们就不用对接口的方法进行实现,构造方法、静态方法也是如上文一样引用。
四、Stream流
将一个来自数据源的队列作为流进行一系列的操作,流并不会保存数据,只能对数据进行操作。
特点:
1、中间操作返回的都是流本身,这样就可以一直调用流的方法。
2、内部迭代(foreach)
方法:foreach(内部迭代遍历),map(映射),filter(过滤),limit(指定数据数量),sort(排序),paraller(并行程序)
,collect(将流归约为list等)。
eg:
List<String> strings = Arrays.asList("g", "b","a", "c");
List<String> collect =
strings.parallelStream().filter(String -> !String.isEmpty()).sorted((o1, o2) -> -1)
.limit(3).map(i -> i + "!").collect(Collectors.toList());
strings.stream().forEach(System.out::println);
System.out.println(collect);
输出:
g
b
a
c
[c!, a!, b!]
并行处理流的同时,输出流。所以首次输出的是尚未处理的流。
五、多重注解
java8允许同一个类型的注解使用多次,只需要给该注解标注一下@Repeatable
即可。