读书笔记--《写给大忙人的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
这个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,而数组是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 {
@Override
//返回正数,零,负数各代表大于,等于,小于
public int compare(Integer o1, Integer o2) {
if (o1 > o2) {
return -1;
} else {
return 1;
}
}
}
}
作用域
lambda表达式的方法体与嵌套代码有着相同的作用域。在lambda表达式中不允许声明一个与局部变量同名的参数或者局部变量。
// 错误
int first = 0;
Comparator 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 consumer = ele -> {
System.out.println(num);
};
//num = num + 2;
consumer.accept("hello");
}
}
如果把注释删掉,则会报错。因为在lambda表达式中只能引用那些值不会改变的变量。