1. 方法引用
什么是方法引用
当要传递给 Lambda 体的操作,已经有实现的方法了,可以使用方法引用! (实现抽象方法的参数列表,必须与方法引用方法的参数列表保持一致!) 方法引用:使用操作符 ::
将方法名和对象或类的名字分隔开来。 如下三种主要使用情况: (抽象方法参数列表里面的参数,第一个参数可被当作对象使用,也可以当作参数使用,其他的参数只能被当作参数使用)
- 对象::实例方法
- 类名::静态方法
- 类名::实例方法
1. 对象::实例方法 示例
public class Main {
public static void main(String[] args) {
System.out.println("--------------抽象方法的参数被当作参数------------------");
System.out.println("--------------正常的写法------------------");
/**
* 正常的写法
*/
PrintStream ps = System.out;
Consumer<String> con1 = (str) -> ps.println(str);
con1.accept("Hello World!");
System.out.println("--------------方法引用 1 ------------------");
/**
* 方法引用:对象::实例方法
* (这里抽象方法的参数被当作参数传给了 println 方法)
*/
Consumer<String> con2 = ps::println;
con2.accept("Hello Java8!");
System.out.println("--------------方法引用 2 ------------------");
/**
* 方法引用:对象::实例方法 (System.out等同于ps)
* (这里抽象方法的参数被当作参数传给了 println 方法)
*/
Consumer<String> con3 = System.out::println;
con3.accept("Hello Java8!");
System.out.println("--------------抽象方法的参数被当作对象------------------");
System.out.println("--------------正常的写法------------------");
/**
* 正常的写法
*/
Function<String , String> fun = (x) -> x.toUpperCase();
System.out.println(fun.apply("Hello Java8!"));
System.out.println("--------------方法引用------------------");
/**
* 方法引用:对象::实例方法
* (这里抽象方法的参数被当作字符串的实例对象,去调用 toUpperCase 方法)
*/
Function<String , String> fun1 = String::toUpperCase;
System.out.println(fun1.apply("Hello Java8!"));
System.out.println("--------------抽象方法无参数------------------");
System.out.println("--------------正常的写法------------------");
pepole pel = new pepole();
pel.setAge(22);
pel.setName("dongkuku");
/**
* 正常的写法
*/
Supplier<String> sup = () -> pel.getName();
System.out.println(sup.get());
System.out.println("--------------方法引用------------------");
/**
* 方法引用:对象::实例方法
*/
Supplier<String> sup1 = pel::getName;
System.out.println(sup1.get());
}
}
class pepole{
private String name ;
private int age ;
public String getName() {return name;}
public void setName(String name) {this.name = name;}
public int getAge() {return age;}
public void setAge(int age) {this.age = age;}
}
2. 类名::静态方法 示例
public class Main {
public static void main(String[] args) {
System.out.println("--------------抽象方法的参数被当作参数------------------");
System.out.println("--------------正常的写法------------------");
Comparator<Integer> com = (x, y) -> Integer.compare(x, y);
System.out.println(com.compare(1 , 2));
System.out.println("--------------方法引用------------------");
/**
* 类名::静态方法名
* (这里抽象方法的参数被当作参数传给了 静态方法 compare)
*/
Comparator<Integer> com1 = Integer::compare;
System.out.println(com1.compare(2 , 1));
System.out.println("--------------抽象方法的参数被当作参数------------------");
System.out.println("--------------正常的写法------------------");
BiFunction<Double, Double, Double> fun = (x, y) -> Math.max(x, y);
System.out.println(fun.apply(1.5, 22.2));
System.out.println("--------------方法引用------------------");
/**
* 类名::静态方法名
* (这里抽象方法的参数被当作参数传给了 静态方法 max)
*/
BiFunction<Double, Double, Double> fun1 = Math::max;
System.out.println(fun1.apply(1.2, 1.5));
}
}
3. 类名::实例方法 示例
public class Main {
public static void main(String[] args) {
System.out.println("--------------抽象方法的参数被当作参数和对象------------------");
System.out.println("--------------正常的写法------------------");
BiPredicate<String, String> bp = (x, y) -> x.equals(y);
System.out.println(bp.test("abcde", "abcdef"));
System.out.println("--------------方法引用------------------");
/**
* 类名::实例方法名
* (这里抽象方法的第一个参数被当作字符串的实例对象,去调用 equals 方法
* 第二个参数被当作参数传递给了 equals 方法)
*/
BiPredicate<String, String> bp2 = String::equals;
System.out.println(bp2.test("abc", "abc"));
System.out.println("--------------抽象方法的参数被当作对象------------------");
System.out.println("--------------正常的写法------------------");
/**
* 类名::静态方法名
* (这里抽象方法的参数被当作people的实例对象,去调用 getName 方法)
*/
pepole pel = new pepole();
pel.setName("dongkuku");
Function<pepole, String> fun = (e) -> e.getName();
System.out.println(fun.apply(pel));
System.out.println("--------------方法引用------------------");
Function<pepole, String> fun2 = pepole::getName;
System.out.println(fun2.apply(pel));
}
}
class pepole{
private String name ;
private int age ;
public String getName() {return name;}
public void setName(String name) {this.name = name;}
public int getAge() {return age;}
public void setAge(int age) {this.age = age;}
}
4. 总结
注意:
① 方法引用所引用的方法的参数列表与返回值类型,需要与函数式接口中抽象方法的参数列表和返回值类型保持一致!
② 若Lambda 的参数列表的第一个参数,是实例方法的调用者(也就是第一个参数被当作对象),第二个参数(或无参)是实例方法的参数时,可以这样写:格式: ClassName::MethodName
,也就是上面的第三种写法 类名::实例方法
2. 构造器引用
构造器应用与函数式接口相结合,自动与函数式接口中方法兼容。
构造器引用 :构造器的参数列表,需要与函数式接口中参数列表保持一致!具体使用类的哪个构造方法来创建实例对象和函数式接口中抽象方法的参数列表的个数和参数列表的参数类型有关系
构造器引用格式:类名::new
数组引用格式:类名[]::new
1. 构造器引用和数组引用 示例
public class Main {
public static void main(String[] args) {
System.out.println("------------正常写法 新建字符串数组--------------");
Function<Integer, String[]> fun = (args) -> new String[args];
String[] strs = fun.apply(10);
System.out.println(strs.length);
System.out.println("------------数组引用 新建字符串数组--------------");
Function<Integer, String[]> fun2 = String[] :: new;
String[] emps = fun2.apply(10);
System.out.println(emps.length);
System.out.println("------------正常写法 新建people对象 调用一个参数的构造方法--------------");
/**
* 调用一个参数的构造方法
*/
Function<String, pepole> fun3 = (x)->new pepole(x);
pepole pel = fun3.apply("dongkuku");
System.out.println(pel.toString());
System.out.println("------------构造器写法 新建people对象 调用一个参数的构造方法--------------");
Function<String, pepole> fun4 = pepole::new;
pepole pel1 = fun4.apply("dongkuku");
System.out.println(pel1.toString());
System.out.println("------------正常写法 新建people对象 调用无参构造方法--------------");
/**
* 调用无参构造方法
*/
Supplier<pepole> sup = ()->new pepole();
pepole pel2 = sup.get();
System.out.println(pel2.toString());
System.out.println("------------构造器写法 新建people对象 调用无参构造方法--------------");
Supplier<pepole> sup1 = pepole::new;
pepole pel3 = sup1.get();
System.out.println(pel3.toString());
}
}
class pepole{
private String name ;
private int age ;
public pepole() {}
public pepole(String name) {this.name = name;}
public pepole(String name, int age) {this.name = name;this.age = age;}
public String getName() {return name;}
public void setName(String name) {this.name = name;}
public int getAge() {return age;}
public void setAge(int age) {this.age = age;}
@Override
public String toString() {
return "pepole{" +"name='" + name + '\'' +", age=" + age +'}';}
}