1. 接口的默认方法和静态方法
java8 以前的接口是不允许定义有方法体的方法,java8允许在接口中定义有方法体的方法,那么怎么定义呢?
默认方法,使用default关键字定义,语法如下:
public interface Person{
// 和普通方法定义一致,只是使用了default关键字修饰
default String sayHello(String name){
System.out.println("hello everyone, my name is "+name);
}
}
注:默认方法可以被继承和重写
静态方法的定义
public interface Person{
public static void sleep(){
System.out.println("sleepping ...");
}
}
注: 接口原有的特性不变,只是java8在其基础上增加了新特性
2. 引入默认方法和静态方法的好处
java8之前编写的接口在实现时必须重写接口中所有方法,java8提供了默认和静态方法可以使用接口在被实现时可以不用重写接口中的方法(直接继承)
java8在以往java版本的许多接口中新增了很多方法,但是这些接口实现的位置可能会有很多,不可能在java API中找出这些接口的所有实现的位置然后实现新增的方法。因此,java8的设计中引入了接口默认方法和静态方法,在提供默认方法和静态方法后,就可以将新增的方法直接编写在接口中,且实现类中直接继承接口的默认方法和静态方法而不是实现,这样就可以在原有接口上直接新增新的方法,保证了兼容性,也避免了修改java API的繁重工作量。
案例: 可以对比java7和java8中的Comparator接口,可以直接打开源码进行查看,对比两个版本的代码差异。
3. 什么是函数式接口
只有一个抽象方法的接口就是函数式接口,函数式接口使用注解@FunctionalInterface进行标志,当使用该注解标志后接口就成为了一个函数式接口且只有一个抽象方法,函数式接口是lambda表达式的基础。
函数式接口的特性:
a. 只有一个抽象方法
b. 函数式接口中可以定义java.lang.Object中的方法(非final方法)
c. 函数式接口中可以定义多个默认方法和静态方法
☆lambda表达式是函数式接口的实现
@FunctionalInterface
public interface Fun{
// 只有一个抽象方法
public void fun();
default void f1(){
// ...
}
default void f2(){
// ...
}
public static void f3(){
// ...
}
public String toString();
}
4. 初识lambda表达式
@FunctionalInterface
public interface Fun{
// 只有一个抽象方法
public void fun();
}
对于接口中的方法可以使用匿名内部类的方式实现
Fun f = new Fun(){
@Override
public void fun(){
System.out.println("I'm fun()");
}
};
// lambda - 函数式接口的实现
Fun f = () -> System.out.println("I'm fun()");
语法: (参数列表) -> 方法体;
说明:
参数列表使用() 括起来; -> 是分隔符,唯一的作用就是将参数列表和方法实现分隔开
当参数列表为空时, () 不能被省略; 如果方法体只有一条语句可以不用 {} 括起来
5. Lambda案例之List集合排序
// 1. 使用匿名内部类实现Comparator接口
List<String> l = new ArrayList<String>();
l.add("d");
l.add("c");
l.add("b");
l.add("e");
l.add("a");
Collections.sort(l, new Comparator<String>(){
@Oerride
public int compare(String o1, String o2){
return o1.compareTo(o2);
}
});
System.out.println(l);
// 2. Comparator是一个函数式接口, 使用Lambda表达式代替Comparator接口实现
Collections.sort(l,(o1,o2) -> o1.compareTo(o2));
6. java8内置功能接口
public interface Predicate<T>{
public boolean test(T t);
}
public interface Supplier<T>{
public T get();
}
public interface Consumer<T>{
accept(T t);
}
public interface Function<T, R> {
public R apply(T t);
}
7. 方法引用
方法引用一共有4种: 静态方法引用、实例方法引用、任意类方法引用、构造方法引用
静态方法引用
public class TestLambda {
@FunctionalInterface
public interface Fun {
public void run();
}
// 提供一个静态方法
public static void run(){
System.out.println("static function reference ...");
}
public static void main(String[] args){
// lambda表达式方式, 现在将lambda中的代码移到静态方法中,使用方法引用简化lambda表达式
Fun f1 = () -> System.out.println("static function reference ...");
// 语法: 类名::方法名
Fun f2 = TestLambda :: run;
f1.run();
f2.run();
}
}
实例方法引用
public class TestLambda {
@FunctionalInterface
public interface Fun {
public void run();
}
// 提供一个普通成员方法
public void run(){
System.out.println("instance function reference ...");
}
public static void main(String[] args){
// lambda表达式方式, 现在将lambda中的代码移到静态方法中,使用方法引用简化lambda表达式
Fun f1 = () -> System.out.println("instance function reference ...");
TestLambda tl = new TestLambda();
// 语法: 对象::方法名
Fun f2 = tl :: run;
f1.run();
f2.run();
}
}
☆任意类方法引用 (没有搞懂意思)
构造方法引用
对一个类的构造方法引用
public class User {
public User(){}
// ...
}
Supplier su = User :: new;
User u = su.get();
// lambda表达式方式, 创建实例的方法可以使用构造方法, 上面是对构造方法的引用
Supplier su2 = () -> new User();
User u2 = su2.get();
8. Stream API
是针对集合操作提供的一组API, 和java IO流没有半毛钱关系
filter - 过滤器
sorted - 排序
match - 匹配
map - 映射
parallel - Stream的并行
9. 新的时间API
10. Base64 编解码