默认接口方法
Java 8使我们能够通过使用 default
关键字向接口添加非抽象方法实现。 此功能也称为虚拟扩展方法。这个是比较大的一个变更,以往我们的认知是,接口里只能有方法的定义不能有方法的实现,现在使用default关键字,可以在接口中实现方法的具体内容,如下 sqrt:
interface Formula{
double calculate(int a);
default double sqrt(int a) {
return Math.sqrt(a);
}
}
好处是,当我们想对接口扩充时,不需要再去逐一修改接口的所有实现类。很赞的更新。
lambda表达式
有了lambda表达式,方便了我们对内部对象写法的简化,如下:
/**
*以往的写法
*/
List<String> names = Arrays.asList("peter", "anna", "mike", "xenia");
Collections.sort(names, new Comparator<String>() {
@Override
public int compare(String a, String b) {
return b.compareTo(a);
}
});
/**
*新写法
*/
Collections.sort(names, (String a, String b) -> {
return b.compareTo(a);
});
简化了不是一点两点,而且代码逻辑上也更加清晰。注意,lambda表达式写内部类时,可以调用外部变量,且不加final,但是,外部变量同以前一样,是不可以修改的,否则无法通过编译。
函数式接口
函数式接口是融合lambda表达式的扩充,它的定义很简单,只要接口只有一个方法,这个接口就是函数式接口(只有一个方法,这个接口的职能像函数一样单一)。java.lang.Runnable
与 java.util.concurrent.Callable
是函数式接口最典型的两个例子。加不加@FunctionalInterface都可以,jvm可以判断出来,一般建议在接口上使用@FunctionalInterface
注解进行声明,这样的话,编译器如果发现你标注了这个注解的接口有多于一个抽象方法的时候会报错的。用法如下:
Runnable runnable=()->{
System.out.print("这里是自定义的run方法....");
};
//对比以前的写法:
Runnable run=new Runnable() {
@Override
public void run() {
}
};
写起来,非常方便。
Stream流
Java 8扩展了集合类,可以通过 Collection.stream() 或者 Collection.parallelStream() 来创建一个Stream,java.util.Stream
表示能应用在一组元素上一次执行的操作序列。说白了就是可以在Collection类型的一组元素,做一些操作,比如,筛选,排序,匹配之类的,要注意的是,返回的值是操作的副本,对原来的数据没有影响,以筛选(过滤)为例:
//这个是操作的list,元素假设是[a1,b1,c1,d1]
stringList
.stream()
.filter((s) -> s.startsWith("a"))
.forEach(System.out::println);//a1