1 方法引用
在使用 lambda 表达式的时候,实际上传递进去的代码就是一种解决方案:用什么参数做什么操作。考虑一种情况:在lambda 表达式中所指定的操作方案,已经有地方存在相同的方案,是否有必要再写重复的逻辑?
package com.tzb.methodrefer.demo01;
@FunctionalInterface
public interface Printable {
public abstract void print(String s);
}
public class Demo01Printable {
// 定义一个方法,参数传递 Printable 接口,对字符串进行打印
public static void printString(Printable p){
p.print("HelloWorld");
}
public static void main(String[] args){
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);
}
}
1.1 通过对象名引用成员方法
public class MethodRefObject {
public void printUpperCaseString(String str){
System.out.println(str.toUpperCase());
}
}
1.2 通过类名引用静态成员方法
- 类已经存在,静态成员方法也已经存在,就可以通过类名直接引用静态成员方法
- 接口
@FunctionalInterface
public interface Callable {
public abstract int calsAbs(int num);
}
public class Demo02Test {
// 方法的参数要传递计算绝对值的整数,和函数式接口 Callable
public static int method(int number, Callable c) {
return c.calsAbs(number);
}
public static void main(String[] args) {
final int res = method(-10, (n) -> {
return Math.abs(n);
});
System.out.println(res);
// 使用方法引用优化 lambda 表达式
final int n = method(-100, Math::abs);
System.out.println(n);
}
}
1.3 通过 super 引用成员方法
如果存在继承关系,当 lambda 中需要出现 super 调用时,也可以使用方法引用进行替代。
@FunctionalInterface
public interface Greetable {
public abstract void greet();
}
/**
* @Description 定义父类
* @Author tzb
* @Date 2020/12/2 18:35
* @Version 1.0
**/
public class Human {
public void sayHello(){
System.out.println("我是父类");
}
}
public class Man extends Human {
@Override
public void sayHello() {
System.out.println("我是子类");
}
public void method(Greetable g){
g.greet();
}
public void show(){
/*method(()->{
// 创建父类
Human h = new Human();
h.sayHello();
});*/
/*method(()->{
super.sayHello();
});*/
/*
使用 super 引用类的成员方法
super 是已经存在的
父类的成员方法 sayHello 也是已经存在的
所以可以直接使用 super 引用父类的成员方法
*/
method(super::sayHello);
}
public static void main(String[] args) {
new Man().show();
}
}
1.4 通过 this 引用成员方法
this
代表当前对象,如果需要引用的方法就是当前类中的成员方法,可以使用this::成员方法
的格式来使用方法引用。
@FunctionalInterface
public interface Richable {
void buy();
}
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();
}
}
1.5 类的构造器引用
由于构造器的名称和类名完全一样,构造器引用 类名称::new
public class Person {
public Person() {
}
public Person(String name) {
this.name = name;
}
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
@FunctionalInterface
public interface PersonBuilder {
// 定义一个方法,根据传递的姓名,创建 Person对象返回
Person builderPerson(String name);
}
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) {
// 方法参数PersonBuilder接口是一个函数式接口,可以传递 Lambda
/* printName("Mike",(String name)->{
return new Person(name);
});*/
/*
使用方法引用优化lambda 表达式
*/
printName("Jenny",Person::new); // 使用Person 类的带参构造方法,通过传递的姓名创建对象
}
}
1.6 数组的构造器引用
@FunctionalInterface
public interface ArrayBuilder {
int[] builderArray(int length);
}
public class Demo {
public static int[] createArray(int len,ArrayBuilder ab){
return ab.builderArray(len);
}
public static void main(String[] args) {
/*final int[] array = createArray(10, (len) -> {
return new int[10];
});
System.out.println(array.length);*/
int[] arr2 = createArray(10, int[]::new);
System.out.println(Arrays.toString(arr2));
System.out.println(arr2.length);
}
}