lambda
函数式接口
当一个接口定义且仅定义了一个方法时,被称作函数式接口,我们可以用@FunctionalInterface注解来约束一个接口为函数式接口:
@FunctionalInterface
interface FunctionalInterface{
int i=12;
void IsOpen();
}
使用lambda表达式定义接口对象
在实例化一个接口对象的时候,可以利用lamba表达式直接定义接口对象和对应的实现,lambda可以用在变量声明、方法定义中,格式为:
(参数列表) -> action
其中的action可以为一段代码块(方法实体),一个变量(作为方法的返回值),一行代码(针对void)。例如可以用来很方便的创建一个匿名内部类,创建一个新线程:
new Thread(
() -> System.out.print("hello")
).start();
单一的变量可以将参数列表的括号去掉(不建议这样做),参数列表可以有也可以没有类型声明,下面是一个lambda的例子:
public class LambdaTest {
@FunctionalInterface
interface LambdaFun1{ //接口1
String s="";
void get(int a);
}
@FunctionalInterface
interface LambdaFun2{ //接口2
int get(int a,int b);
}
public static void main(String args[]){
LambdaFun1 t1 = a -> System.out.print(a+1);//注意a是形参,形参不能与变量名冲突
LambdaFun2 t2 = (c,d) -> c+d;
}
}
lambda表达式多用于函数式接口中,但也复写那些参数列表唯一的方法生成对象
方法引用
是在某种程度上对已实现方法的lambda表达式的一种优化,格式为 ::,两冒号前为数据类型,可以是类或是既有的对象,冒号后是执行的方法,一个典型的应用就是集合类的compare,我们写了一个类并且定义了compare方法,为了更高的自由度我们并没有选择继承Comparable接口的方式:
class Person{
int age;
String name;
Person(int age,String name){
this.age=age;
this.name=name;
}
@Override
public String toString() {
return age+" ";
}
public static int compareTo(Person a,Person b) {
return a.age-b.age; //递增排列。用于方法引用,实现了倒序排列使用静态免去了实例化
}
}
我们知道若想排序需要在sort的第二个参数定义一个函数式接口Comparator对象并重写它的compare方法,对于既有的方法,可以依赖方法引用实现:
public static void main(String args[]){
Arrays.sort(pArr,(a,b) ->a.age-b.age); //
for(int i=0;i<pArr.length;i++){
System.out.print(pArr[i]);
}
List<Person> pArr = new ArrayList<>();
pArr.add(new Person(12,"Cosl"));
pArr.add(new Person(15, "Jack"));
pArr.add(new Person(13, "sherk"));
pArr.forEach(System.out::print); //foreach也是一种应用
Collections.sort(pArr,Person::compareTo); //用方法引用实现
Collections.sort(pArr,(a,b) -> a.age-b.age); //直接写lambda
Collections.sort(pArr,(a,b) -> Person.compareTo(a,b)); //引用静态方法的lambda
Collections.sort(pArr, new Comparator<Person>() { //直接使用
@Override
public int compare(Person a, Person b) {
return a.age-b.age;
}
}
pArr.forEach(System.out::print);
}
输出:12 15 13 12 13 15

