Java基礎(chǔ)之方法引用(JDK1.8新特性)
方法引用
方法引用是通過方法的名字來指向一個(gè)方法,方法引用可以是語言更緊湊簡潔,減少冗余代碼。
方法引用使用一對冒號 ::
有現(xiàn)成的方法可以完成你想要傳遞到其他代碼的某個(gè)動(dòng)作,
例如假設(shè)你希望只要出現(xiàn)一個(gè)定時(shí)器事件就打印這個(gè)事件對象,你可以調(diào)用Timer timer = new Timer(1000, even -> System.out.println(even))
你也可以直接把println方法傳遞到Timer構(gòu)造器,具體的做法是:
Timer timer1 = new Timer(1000,System.out::println)
表達(dá)式System.out::println 是一個(gè)方法引用,它等價(jià)于lambda表達(dá)式x->System.out.println(x)
2. 假如你想對字符串排序,而不考慮字母的大小寫,可以傳遞一下方法表達(dá)式:
Arrays.sort(strings,String::compareToIgnore)
從這些例子可以看出,要用 :: 操作符分隔方法名與對象或類名。主要有3種情況:
object::instanceMethod
Class::staticMethod
Class::instanceMethod
在前2種情況中,方法引用等價(jià)于提供方法參數(shù)的lambda表達(dá)式。前面已經(jīng)提到,System.out.println等價(jià)于
x->System.out.println(x)。類似得,Math::pow等價(jià)于(x,y)->Math.pow(x,y)
對于第3種情況,第1個(gè)參數(shù)會(huì)成為方法的目標(biāo),例如:String::compareToIgnoreCase等同于(x,y)->x.compareToIgnoreCase(y)
實(shí)例如下:
@FunctionalInterface
public interface Supplier<T> {
T get();
class Car{
/**
//Supplier是jdk1.8的接口,這里和lambda一起使用了
* @param supplier
* @return
*/
public static Car create(final Supplier<Car> supplier) {
return supplier.get();
}
public static void collide(final Car car) {
System.out.println("collided " + car.toString());
}
public void follow(final Car another) {
System.out.println("Following the " + another.toString());
}
public void repair() {
System.out.println("Repaired " + this.toString());
}
public static void main(String[] args) {
//構(gòu)造器引用,它的語法是Class::new,或者更一般的Class<T>::new實(shí)例
final Car car = Car.create(Car::new);
final List<Car> cars = Arrays.asList(car);
//靜態(tài)方法引用:它的語法是Class::static_method,實(shí)例如下:
cars.forEach(Car::collide);
//特定類的任意對象的方法引用:它的語法是Class::method
cars.forEach(Car::repair);
//特定對象的方法引用:它的語法是instance::method
final Car police = Car.create(Car::new);
cars.forEach(police::follow);
}
}
}
再談Comparator
Comparator 接口包含很多方便的靜態(tài)方法來創(chuàng)建比較器。這些方法可以用于lambda表達(dá)式或者方法引用
靜態(tài)comparing 方法取一個(gè)"鍵提取器"函數(shù),它將類型T映射為一個(gè)課比較的類型(如String)。對要比較的對象
應(yīng)用這個(gè)函數(shù),然后對返回的鍵完成比較。例如,假設(shè)有一個(gè)Person對象數(shù)組,可以如下按名字對這些對象排序:
Arrays.sort(people,Comparator.comparing(Person::getName))
我們來看一個(gè)完整的例子:
public class PersonCompartor {
public static void main(String[] args) {
People person = new People();
person.setId(111);
person.setName("zhangsan");
People person1 = new People();
person1.setId(12);
person1.setName("zhangsan");
People person2 = new People();
person2.setId(31);
person2.setName("an三");
People person3 = new People();
person3.setId(21);
person3.setName("an一11111111");
People[] peopleArray = new People[]{person,person1,person2,person3};
//1、按照人名排序
Arrays.sort(peopleArray, Comparator.comparing(People::getName));
System.out.println("第一次排序結(jié)果:"+JSON.toJSONString(peopleArray));
//2、人名相同的情況下,按照id排序
Arrays.sort(peopleArray,Comparator.comparing(People::getName).thenComparing(People::getId));
System.out.println("第二次排序結(jié)果:"+JSON.toJSONString(peopleArray));
//3、根據(jù)人名長度完成排序:,提取了的鍵指定一個(gè)比較器
Arrays.sort(peopleArray, Comparator.comparing(People::getName, (s, t) -> Integer.compare(s.length(), t.length())));
System.out.println("第三次排序結(jié)果:"+JSON.toJSONString(peopleArray));
//4、第三種方法的變體
Arrays.sort(peopleArray,Comparator.comparing(p->p.getName().length()));
System.out.println("第四次排序結(jié)果(同第三次):"+JSON.toJSONString(peopleArray));
}
}
運(yùn)行結(jié)果是:
第一次排序結(jié)果:[{"id":21,"name":"an一11111111"},{"id":31,"name":"an三"},{"id":111,"name":"zhangsan"},{"id":12,"name":"zhangsan"}]
第二次排序結(jié)果:[{"id":21,"name":"an一11111111"},{"id":31,"name":"an三"},{"id":12,"name":"zhangsan"},{"id":111,"name":"zhangsan"}]
第三次排序結(jié)果:[{"id":31,"name":"an三"},{"id":12,"name":"zhangsan"},{"id":111,"name":"zhangsan"},{"id":21,"name":"an一11111111"}]
第四次排序結(jié)果(同第三次):[{"id":31,"name":"an三"},{"id":12,"name":"zhangsan"},{"id":111,"name":"zhangsan"},{"id":21,"name":"an一11111111"}]
參考
Java 8 方法引用
作者:碼農(nóng)飛哥
微信公眾號:碼農(nóng)飛哥