1. 方法引用
若lambda體中的內容有方法已經實現了,我們可以使用‘方法引用’,可以理解為方法引用是lambda表達式的另外一種表現形式
。雙冒號形式
主要有三種語法格式
使用要求(注意點):
- Lambda體中調用方法的
參數列表、返回值類型
,必須要和接口實現方法
的參數列表、返回值保持一致
1.1. 對象::實例方法名
//1.1. 對象::實例方法名
@Test
public void test1(){
Consumer<String> con = (x) -> System.out.println(x);
con.accept("hxh");//hxh
Consumer<String> con1 = System.out::println;
con1.accept("hxh");//hxh 結果一致
//Consumer<T> 接口中的方法為: void accept(T t);
// println()方法實現為: public void println(String x)
/**
* 此處可以使用方法引用是因為 引用的方法println()的參數列表和返回值的類型 void println(String x)
* 與 Consumer<String> 接口實現的方法中的 void accept(String t) 的參數列表和返回值的類型
*/
}
1.2. 類::靜態方法名
@Test
public void test2(){
Supplier<String> sup = () -> new Object().toString();
System.out.println(sup.get()); //java.lang.Object@7d6f77cc
Supplier<String> sup1 = new Object()::toString;
System.out.println(sup1.get()); // java.lang.Object@6f75e721
Supplier<Double> sup2 = () -> Math.random();
System.out.println(sup2.get()); // 0.3782071825902372
Supplier<Double> sup3 = Math::random;
System.out.println(sup3.get()); // 0.1516143754943341
}
1.3. 類::實例方法名
該類型使用條件:
-
第一個參數
是實例方法的調用者
,第二個參數
是實例方法的參數
//類::實例方法名
@Test
public void test3(){
//BiPredicate<T,U> 倆參數的斷言型接口
BiPredicate<String,String> bp = (x,y) -> x.equals(y);
System.out.println(bp.test("hxh","hxh")); //true
//(x,y) 括號里倆參數 第一個參數是調用方法對象,第二個參數是方法參數
BiPredicate<String,String> bp1 = String::equals;
System.out.println(bp1.test("hxh", "aaj"));//false
}
2. 構造器引用
- 構造器,創建對象,
自動匹配類中對應的構造器(參數不定)
- 需要調用的
構造器的參數列表
要和函數式接口中的抽象方法參數列表
保持一致
語法:
ClassName::new;
實體類 Stu
public class Stu {
private Integer id;
private String name;
private Integer age;
public Stu() {
}
public Stu(Integer id) {
this.id = id;
}
public Stu(Integer id, Integer age) {
this.id = id;
this.age = age;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
@Override
public String toString() {
return "Stu{" +
"id=" + id +
", name='" + name + '\'' +
", age=" + age +
'}';
}
}
測試用例:
@Test
public void test4(){
//無參構造
Supplier<Stu> stuSupplier = ()-> new Stu();
System.out.println(stuSupplier.get());
//自動匹配類中和接口實現的抽象方法中參數列表一致的構造器(無參構造器)
Supplier<Stu> stuSupplier1 = Stu::new;
System.out.println(stuSupplier1.get());
//Stu{id=null, name='null', age=null}
//有一個參數的構造
Function<Integer,Stu> s1 = (x) -> new Stu(x);
System.out.println(s1.apply(1)); //Stu{id=1, name='null', age=null}
//自動匹配類中和接口實現的抽象方法中參數列表一致的構造器(單個Integer的構造器)
Function<Integer,Stu> s2 = Stu::new;
System.out.println(s2.apply(2)); //Stu{id=2, name='null', age=null}
//有兩個參數的構造 BiFunction<T, U, R> R apply(T t, U u);
BiFunction<Integer,Integer,Stu> bf = (x,y) -> new Stu(x,y);
System.out.println(bf.apply(3,44)); //Stu{id=3, name='null', age=44}
//自動匹配類中和接口實現的抽象方法中參數列表一致的構造器(兩個個Integer的構造器)
BiFunction<Integer,Integer,Stu> bf1 = Stu::new;
System.out.println(bf1.apply(4,55));//Stu{id=4, name='null', age=55}
}
3. 數組引用
語法:
Type[]::new;
//數組引用 Type[]::new
@Test
public void test5(){
//創建指定長度的字符串數組
Function<Integer,String[]> f1 = (x) -> new String[x];
System.out.println(f1.apply(10).length); //10
Function<Integer,String[]> f2 = String[]::new;//數組引用 可以直接代替
System.out.println(f2.apply(20).length); //20
}