Java基礎之方法引用(JDK1.8新特性)

方法引用

方法引用是通過方法的名字來指向一個方法,方法引用可以是語言更緊湊簡潔,減少冗餘代碼。
方法引用使用一對冒號 ::
有現成的方法可以完成你想要傳遞到其他代碼的某個動作,

  1. 例如假設你希望只要出現一個定時器事件就打印這個事件對象,你可以調用Timer timer = new Timer(1000, even -> System.out.println(even))

你也可以直接把println方法傳遞到Timer構造器,具體的做法是:
Timer timer1 = new Timer(1000,System.out::println)

表達式System.out::println 是一個方法引用,它等價於lambda表達式x->System.out.println(x)
2. 假如你想對字符串排序,而不考慮字母的大小寫,可以傳遞一下方法表達式:
Arrays.sort(strings,String::compareToIgnore)

從這些例子可以看出,要用 :: 操作符分隔方法名與對象或類名。主要有3種情況:

  • object::instanceMethod
  • Class::staticMethod
  • Class::instanceMethod
    在前2種情況中,方法引用等價於提供方法參數的lambda表達式。前面已經提到,System.out.println等價於
    x->System.out.println(x)。類似得,Math::pow等價於(x,y)->Math.pow(x,y)

對於第3種情況,第1個參數會成爲方法的目標,例如:String::compareToIgnoreCase等同於(x,y)->x.compareToIgnoreCase(y)
實例如下:

@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) {
            //構造器引用,它的語法是Class::new,或者更一般的Class<T>::new實例
            final Car car = Car.create(Car::new);
            final List<Car> cars = Arrays.asList(car);
            //靜態方法引用:它的語法是Class::static_method,實例如下:
            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 接口包含很多方便的靜態方法來創建比較器。這些方法可以用於lambda表達式或者方法引用

靜態comparing 方法取一個"鍵提取器"函數,它將類型T映射爲一個課比較的類型(如String)。對要比較的對象

應用這個函數,然後對返回的鍵完成比較。例如,假設有一個Person對象數組,可以如下按名字對這些對象排序:
Arrays.sort(people,Comparator.comparing(Person::getName))

我們來看一個完整的例子:

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("第一次排序結果:"+JSON.toJSONString(peopleArray));
        //2、人名相同的情況下,按照id排序
        Arrays.sort(peopleArray,Comparator.comparing(People::getName).thenComparing(People::getId));
        System.out.println("第二次排序結果:"+JSON.toJSONString(peopleArray));
        //3、根據人名長度完成排序:,提取了的鍵指定一個比較器
        Arrays.sort(peopleArray, Comparator.comparing(People::getName, (s, t) -> Integer.compare(s.length(), t.length())));
        System.out.println("第三次排序結果:"+JSON.toJSONString(peopleArray));
        //4、第三種方法的變體
        Arrays.sort(peopleArray,Comparator.comparing(p->p.getName().length()));
        System.out.println("第四次排序結果(同第三次):"+JSON.toJSONString(peopleArray));
    }
}

運行結果是:

第一次排序結果:[{"id":21,"name":"an一11111111"},{"id":31,"name":"an三"},{"id":111,"name":"zhangsan"},{"id":12,"name":"zhangsan"}]
第二次排序結果:[{"id":21,"name":"an一11111111"},{"id":31,"name":"an三"},{"id":12,"name":"zhangsan"},{"id":111,"name":"zhangsan"}]
第三次排序結果:[{"id":31,"name":"an三"},{"id":12,"name":"zhangsan"},{"id":111,"name":"zhangsan"},{"id":21,"name":"an一11111111"}]
第四次排序結果(同第三次):[{"id":31,"name":"an三"},{"id":12,"name":"zhangsan"},{"id":111,"name":"zhangsan"},{"id":21,"name":"an一11111111"}]

參考

Java 8 方法引用

發佈了144 篇原創文章 · 獲贊 24 · 訪問量 9萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章