1、Lambda表达式优化
双冒号::为引用运算符,而它所在的表达式被称为方法引用。如果Lambda要表达的函数方案已经存在于某个方法的实现中,那么则可以通过双冒号来引用该方法作为Lambda表达式替代
public class Demo01Printable {
//定义一个方法,参数传递Printable接口,对字符串进行打印
public static void printString(Printable p) {
p.print("HelloWorld");
}
public static void main(String[] args) {
//调用printString方法,方法的参数Printable是一个函数式接口,所以可以传递Lambda
printString((s) -> {
System.out.println(s);
});
/*
分析:
Lambda表达式的目的,打印参数传递的字符串
把参数s,传递给了System.out对象,调用out对象中的方法println对字符串进行了输出
注意:
1.System.out对象是已经存在的
2.println方法也是已经存在的
所以我们可以使用方法引用来优化Lambda表达式
可以使用System.out方法直接引用(调用)println方法
*/
printString(System.out::println);
}
}
2、使用对象名引用成员方法
// Printable interface
@FunctionalInterface
public interface Printable {
void print(String s);
}
// MethodRefObject.java
public class MethodRefObject {
// 定义成员方法
public void printUpperCaseString(String str) {
System.out.println(str.toUpperCase());
}
}
// Demo01ObjectMethodReference.java
// 通过对象名引用成员方法
// 使用前提是对象名是已经存在的,成员方法也是已经存在的
public class Demo01ObjectMethodReference {
public static void printString(Printable p) {
p.print("Hello World");
}
public static void main(String[] args) {
printString(s -> {
MethodRefObject obj = new MethodRefObject();
obj.printUpperCaseString(s);
});
// 使用对象名引用成员方法
printString(new MethodRefObject()::printUpperCaseString);
}
}
3、通过类名引用静态成员方法
// Calcable
@FunctionalInterface
public interface Calcable {
int calsAbs(int number);
}
// Demo01StaticMethodReference
public class Demo01StaticMethodReference {
public static void main(String[] args) {
int num = method(-10, n-> {
return Math.abs(n);
});
System.out.println(num);
// 静态方法引用
System.out.println(method(-10, Math::abs));
}
// 定义一个方法,方法的参数要定义一个绝对值的整数,和函数式接口 calcable
public static int method(int number, Calcable c) {
return c.calsAbs(number);
}
}
4、通过super引用成员方法
如果存在继承关系,当Lambda中需要出现super调用时,也可以使用方法引用进行代替
// Greetable interface
@FunctionalInterface
public interface Greetable {
void greet();
}
// 父类 Human.java
public class Human {
public void sayHello() {
System.out.println("Hello 我是Human");
}
}
// 子类 Man.java
public class Man extends Human{
// 重写
@Override
public void sayHello() {
System.out.println("Hello 我是man");
}
public void method(Greetable g) {
g.greet();
}
public void show() {
// 调用method方法
method(()-> {
Human h = new Human();
h.sayHello();
});
// 因为存在子父类关系,所以存在的一个关键字super,代表父类,我们可以直接使用super调用父类的成员方法
method(()-> {
super.sayHello();
});
// 使用super引用成员方法,super是存在的,父类的sayHello也是存在的,所以可以直接使用super引用父类的成员方法
method(super::sayHello);
}
public static void main(String[] args) {
new Man().show();
}
}
5、使用this引用本类的成员方法
// Richable interface
@FunctionalInterface
public interface Richable {
void buy();
}
// Husband.java
// 通过this引用本类的成员方法
public class Husband {
public void buyHouse() {
System.out.println("北京二环内买一套四合院");
}
public void marry(Richable r) {
r.buy();
}
public void soHappy() {
marry(() -> {
this.buyHouse();
});
// 优化lambda表达式,this已经存在,buyHouse已经存在的
marry(this::buyHouse);
}
public static void main(String[] args) {
new Husband().soHappy();
}
}
6、使用类构造器引用
// PersonBuilder interface
@FunctionalInterface
public interface PersonBuilder {
// 定义一个方法,根据传递的姓名,创建Person对象
Person builderPerson(String name);
}
// Person.java
public class Person {
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Person() {
}
public Person(String name) {
this.name = name;
}
}
// Demo.java
// 类的构造器
public class Demo {
public static void printName(String name, PersonBuilder pb) {
Person person = pb.builderPerson(name);
System.out.println(person.getName());
}
public static void main(String[] args) {
printName("迪丽热巴", (name)-> {
return new Person(name);
});
/*使用方法引用优化Lambda表达式
* 构造方法new Person已知
* 创建对象的方式也是已知的new
*/
printName("迪丽热巴", Person::new);
}
}
7、数组的构造器引用
// ArrayBuilder interface
@FunctionalInterface
public interface ArrayBuilder {
// 定义一个创建int类型数组的方法
int[] builderArray(int length);
}
// Demo.java
// 数组的构造器引用
public class Demo {
public static int[] createArray(int length, ArrayBuilder ab) {
return ab.builderArray(length);
}
public static void main(String[] args) {
int []arr1 = createArray(10, (len)->{ return new int[len]; });
System.out.println(arr1.length);
/*
* 使用lambda
* 已知创建的数组是 int[] 数组
* 数组的长度也是已知的
* 就可以使用方法引用
* int[] 引用new,根据参数传递的长度来创建数组
* */
int[] arr2 = createArray(10, int[]::new);
System.out.println(arr2.length);
}
}
网友评论