版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/imilano/article/details/79392143
4. 接口、lambda和内部类
Comparator与comparable接口
- comparable接口的方法是compareTo,只有一个参数;comparator接口的方法是compare,有两个参数。
- comparator自定义比较器。comparable实现接口。
对象克隆
- 深拷贝与浅拷贝。如果对象是不可变的,那么默认的浅拷贝也没有问题;否则,就要使用深拷贝。
- 默认的克隆方法是浅拷贝,clone方法是Object的一个protected方法。
要让一个对象可以克隆,则需要如下步骤:
- 实现cloneable接口
- 重定义clone方法,并指定public访问修饰符。
- 重定义的clone方法要逐一拷贝每一个域。
如果一个要clone的对象没有实现cloneable接口,那么编译器就会抛出一个CloneNotSupportedException异常。
- 形似cloneable这样的接口叫做标记接口,标记接口没有实现任何的方法,他的作用只是允许在类型查询中使用instanceOf。
- 即便默认浅拷贝能够满足要求,还是徐亚需要实现Cloneable接口,将clone重新定义为public,再调用super.clone().
lambda表达式
- 传代码而非传值。
lambda的语法规则:
- (参数)->以及一个表达式
- 如果计算无法在一个表达式中完成,那么就使用{}。
- 即使lambda没有参数,任然要提供空括号,就算无参方法一样。
- 如果可以推导出一个lambda表达式的参数类型,则可以忽略其类型。
- 如果方法只要一个参数,而且这个 参数的类型可以推导得出,那么甚至可以省略小括号。
- 无需指定lambda表达式的返回类型。lambda表达式返回类型总可以由上下文推导出。
- 如果一个lambda表达式只在某些分支返回一个值,而在另一些分支不返回,这是不合法的。
- 只有一个抽象方法的接口,称为函数式接口。
- lambda表达式中捕获的变量必须是最终变量,这个变量初始化之后就不能再为他赋新值,不能做更改。
- 在lambda表达式中,声明一个与局部变量同名的参数或局部变量是不可合法的。
- 在一个lambda表达式中使用this关键字,是指创建这个lambda表达式的方法的this参数。
lambda表达式的用法:
- 使用函数式接口:
- 方法引用
- 构造器引用
//函数式接口
import java.util.Arrays;
import java.util.*;
import javax.swing.*;
import javax.swing.Timer;
public class Lambda{
public static void main(String[] args){
String[] planets = new String[]{"mar","Venus","Earth"};
System.out.println(Arrays.toString((planets)));
System.out.println("sorted:");
Arrays.sort(planets);
System.out.println(Arrays.toString(planets));
System.out.println("Sorted by length:");
Arrays.sort(planets,(first,second)->first.length()-second.length());
System.out.println(Arrays.toString(planets));
//lambda表达式
Timer t = new Timer(1000,event->
System.out.println("the time is "+new Date())
);
t.start();
}
}
//方法引用
//方法引用的目的:使用现成的方法完成传递到其他代码的某个动作
Timer t = new Tomer(1000,event->
System.out.println(event)
)
// 使用方法引用,精简如下
Timer t = new Timer(1000,System.out::println);
//构造器引用
//想得到一个Person数组,但是java不支持泛型数组,只能得到Object数组
Object[] people = stream.toArray();
//使用构造器引用解决至这个问题
Person[] people = stream.toArray(Person::new)
//变量作用域问题
//lambd表达式的变量必须是最终变量,不得改变。
public static void countdown(iint start,int delay){
ActionListener listener = event->
{
start--; //Error,不能改变捕捉的值
System.out.println(start);
};
new Timer(delay,listener).start();
}
Path first = Paths.get("/usr/bin");
Comparator<String> comp = (first,second) -> first.length-second.length();
//Error:Variable first already defined