public static void printString(PrintA p) {
p.print("helloworld");
}
public static void main(String[] args) {
//最繁杂写法
printString(new PrintA() {
@Override
public void print(String s) {
System.out.println(s);
}
});
//Lambda表达式的简化版
printString((s) -> System.out.println(s));
//方法引用
printString(System.out::println);
printString(System.out::println);
::
双冒号为引用运算符,所在表达式被称为方法引用
如果Lambda要表达的函数方案已经存在于某个方案语法的实现中,可以用此法代替Lambda
注意:
Lambda中传递的参数一定是方法引用中的那个方法可以接收的类型,否则抛出异常
通过对象名引用成员方法
@FunctionalInterface
public interface PrintB {
void print(String s);
}
public class MethodRerObject {
public void printUpperCase(String str) {
System.out.println(str.toUpperCase());
}
}
public static void printString(PrintB p) {
p.print("hellow");
}
public static void main(String[] args) {
printString(new PrintB() {
@Override
public void print(String s) {
MethodRerObject obj = new MethodRerObject();
obj.printUpperCase(s);
}
});
//Lambda表达式优化
printString((s) -> {
MethodRerObject obj = new MethodRerObject();
obj.printUpperCase(s);
});
//方法引用优化:对象MethodRerObject已经存在
//成员方法printUpperCase已经存在
//创建MethodRerObject对象
MethodRerObject obj = new MethodRerObject();
printString(obj :: printUpperCase);
}
通过类名引用静态成员方法
@FunctionalInterface
public interface Calculate {
int calAbs(int a);
}
public static int absMethod(int a, Calculate cal) {
return cal.calAbs(a);
}
public static void main(String[] args) {
int number = absMethod(-10, new Calculate() {
@Override
public int calAbs(int n) {
return Math.abs(n);
}
});
//Lambda表达式优化
int number2 = absMethod(-10, (n) -> {
return Math.abs(n);
});
//在Lambda基础上优化
//Math工具类存在,absMethod静态方法也存在
int number3 = absMethod(-10, Math::abs);
}
思考:
这几个主题里说的引用,都是在Lambda表达式中,用到的成员方法,静态成员方法。
第一个的obj.printUpperCase(s);
这个的return Math.abs(n);
通过super引用父类成员方法
函数式接口
@FunctionalInterface
public interface Greatable {
void greet();
}
父类
public class Human {
public void sayHello() {
System.out.println("hello,hehe");
}
}
子类
@Override
public void sayHello() {
System.out.println("hello,male");
}
public void method(Greatable g) {
g.greet();
}
public void show() {
//最繁杂方法
method(() -> {
Human h = new Human();
h.sayHello();
});
//因为有子父类关系,存在一个关键字super
//可以直接使用super调用父类方法
method(() -> {
super.sayHello();
});
//方法引用
//Human h = new Human();
//因为存在继承关系,所以上面这个不需要了,super代表父类
method(super::sayHello);
}
public static void main(String[] args) {
new male().show();
}
通过this引用本类成员方法
@FunctionalInterface
public interface Richable {
void buy();
}
public void buyHouse() {
System.out.println("北京四合院");
}
public void getMarry(Richable r) {
r.buy();
}
public void happy() {
getMarry(new Richable() {
@Override
public void buy() {
//为什么不能用这个
//因为这是匿名内部类写法,this只在本匿名内部类起作用
this.; //XXXX!!!
}
});
getMarry(() -> {
this.buyHouse();
});
getMarry(this::buyHouse);
}
public static void main(String[] args) {
new Human().happy();
}
!!!!
此例中,可以看出Lambda表达式并不是新建了一个类,所以this依旧可以代指本类,而使用匿名内部类,this仅仅在内部类起作用,并不能调用本类中的成员方法
Lambda表达式传递的参数,对应重写方法的参数
类的构造器(构造方法)引用
格式:
类名称::new
@FunctionalInterface
public interface PersonInterface {
Person13 builderPerson(String name);
}
public static void printName(String name, PersonInterface p) {
Person13 person = p.builderPerson(name);
System.out.println(person.getName());
}
public static void main(String[] args) {
printName("hehe", (String name) -> {
return new Person13(name);
});
//方法引用
//new Person(String name)构造方法已知
//创建对象 new已知
//使用Person引用new创建对象
printName("hahaha", Person13::new);
}
new Person13(name)
这就是一个有参构造方法
数组的构造器(构造方法)引用
@FunctionalInterface
public interface ArrayBuiler {
int[] buildArray(int length);
}
public static int[] creatArray(int length, ArrayBuiler arr) {
return arr.buildArray(length);
}
public static void main(String[] args) {
int[] arr1 = creatArray(12, (len) -> {
return new int[len];
});
//方法引用
//已知创建int[]数组
//数组长度也已知
int[] ints = creatArray(12, int[]::new);
}
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。