读书笔记 –《写给大忙人的 JavaSE 9 核心技术》—第 3 章
接口和 lambda 表达式
接口
它可以让你在不提供实现的情况下,指定应该做什么。(主要在设计阶段用得到)
示例代码
public interface Test1 {
// 接口中的方法默认为 public
public void saySomething(String something);
// 在接口中可以定义静态方法
// 静态方法只能由这个接口去调用,// 实现此接口的对象是不能调用的。static void sayMyName(){System.out.println("my name is Test1");
}
// 在接口中可以定义默认方法, 实现此接口的类可以重新
// 默认方法结束了这种经典模式——提供一个接口和实现该接口大多数或全部方法的伴随类
default void sayHello(){System.out.println("Hello");
}
}
lambda
参考博文 1
参考博文 2
这个 lambda 表达式 和 JavaScript 里面的箭头函数很像
其核心是一种简写方式, 可以取代大部分的匿名内部类, 写出更优雅的 Java 代码。
// 一行语句
(String s1,String s2) -> s1.length() - s2.length()
// 多行语句
(String s1,String s2) ->{if(s1.length()>s2.length()){return "yes"}else{return "no"}
}
// 无参数
() -> return "666"
// 如果参数类型可以推导出来,则可以省略。// 示例见下方代码
函数式接口
该接口只有一个抽象方法,该接口会被 @FunctionalInterface 这个注解所修饰
当你需要一个实现函数式接口的对象实例时,可以提供一个 lambda 表达式来创建。
import java.util.Arrays;
import java.util.Comparator;
public class Test3 {public int[] sort(int[] s) {//Arrays.sort(s);
Integer[] a = {9, 8, 7, 2, 3, 4, 1, 0, 6, 5};
Comparator myComparator = new MyComparator();
// 自动装包机制不能应用于数组。// 这里 Comparator<Integer>,是 Integer,而数组是 int 类型。这两个不一样!// 要把 int 改为 Integer
// Arrays.sort(s ,myComparator); // 会报错!//Arrays.sort(a, myComparator);
// lambda 表达式简写
Arrays.sort(a, (n1, n2) -> {if (n1 > n2) {return -1;} else {return 1;}
}
);
for (int n : a) {System.out.println(n);
}
return s;
}
class MyComparator implements Comparator<Integer> {
@Override
// 返回正数,零,负数各代表大于,等于,小于
public int compare(Integer o1, Integer o2) {if (o1 > o2) {return -1;} else {return 1;}
}
}
}
作用域
lambda 表达式的方法体与嵌套代码有着相同的作用域。在 lambda 表达式中不允许声明一个与局部变量同名的参数或者局部变量。
// 错误
int first = 0;
Comparator<Integer> comp = (first,second)->first > second
this 指向问题
lambda 表达式中 this 指向创建 lambda 表达式的外部类。
这里的 this 指向 App,而不是 Runnable 实例。这一点和 JavaScript 中的箭头函数很像,this 指向调用此函数的对象。
class App() {public void doWork(){Runnable runnable = ()->{System.out.println(this.toString());
}
}
}
lambda 一般情况下会被编译成静态匿名方法,引用的外部变量以参数的方式传递。
如果 lambda 里使用了 this 指标,则被编译为匿名内部方法,以让 this 指针指向 lambda 外部类。
闭包
闭包就是能够读取其他函数内部变量的函数。
这个概念在 JavaScript 中相当重要
https://developer.mozilla.org…
在 Java 中有了 lambda 表达式,也有了闭包的概念,但是和 JavaScript 中的闭包有些不同。没有 JavaScript 中的强大。
import java.util.function.Consumer;
public class Main {public static void main(String[] args) {
int num = 10;
Consumer<String> consumer = ele -> {System.out.println(num);
};
//num = num + 2;
consumer.accept("hello");
}
}
如果把注释删掉,则会报错。因为在 lambda 表达式中只能引用那些值不会改变的变量。