標籤:parse 安卓 express int 工具類 命令 配置 rip 傳值
前言
上一文:Android 使用Java8新特性之Lambda expression (附命令者模式簡化)
說過lambda運算式,在android studio中的環境配置及應用。本文講下Java8新特性之”方法引用”。
“方法引用”,它其實可以看成lambda運算式的一種簡寫形式。
再回顧一下lambda運算式的應用情境:簡化僅含單一抽象方法介面的調用
方法引用的4種形式
方法引用的符號形式,形如,
[className | class-instance]::[static-method | instance-method | construct-method]
即,以類名或類的執行個體對象為首碼,中間以兩個冒號(::)串連,後跟靜態方法 或 執行個體方法 或 構造方法
分類:
1. 靜態方法引用
2. 執行個體方法引用
3. 類執行個體方法引用
4. 構造方法引用
靜態方法引用
類MethodReferenceActivity下有一靜態方法:
static int parz(String str) {//被lambda運算式或"方法引用"調用 return Integer.parseInt(str);}
如果直接調用 MethodReferenceActivity::parz當然是不行的,因為”方法引用”是用來替換lambda運算式的,所以也將指代一個僅含單一抽象方法的介面。
再有一個介面:
public interface ToIntFunc<T> {//註:原生jdk中就有的方法,安卓中沒有 int applyAsInt(T value);}
再有一個使用ToIntFunc介面的靜態方法:
public static int parse(ToIntFunc<String> f, String num) { return f.applyAsInt(num);}
調用parse()時使用lambda運算式:
int parseValue = parse((value -> parz(value)), num);
調用parse()時使用”方法引用”:
int parseValue = parse(MethodReferenceActivity::parz, num);
執行個體方法引用
將上面的方法parse方法聲明中的static 去掉:
public int parse(ToIntFunc<String> f, String num) { return f.applyAsInt(num);}
調用parse()時使用”方法引用”:
int parseValue = parse(this::parz, num); //this指當前類的執行個體對象
類執行個體方法引用需要在外部調用方法中,聲明參數
如有一個內部類Person:
static class Person { public Person() { } public Person(String name) { this.name = name; } String name; Long birthday; public Long getBirthday() { return birthday; } public String getName() { return name; } public boolean compareByName(Person b) { int result = this.name.compareToIgnoreCase(b.name); if (result == 1) { return true; } else { return false; } } @Override public String toString() { return "Person{" + "name=‘" + name + ‘\‘‘ + ", birthday=" + birthday + ‘}‘; } public void printInfo() { System.out.println(toString()); }}
有一個介面Compare:
public interface Compare<T> { boolean compareTo(T v1, T v2);}
外部的使用介面Compare的調用方法isLarge:
public boolean isLarge(Compare<Person> c, Person p1, Person p2) { return c.compareTo(p1, p2);}
使用lambda運算式和類執行個體方法引用:
Person p1 = new Person("stone");Person p2 = new Person("sun");boolean result = isLarge((v1, v2) -> v1.compareByName(v2), p1, p2);System.out.println("p1 排序在 p2 後: " + result);result = isLarge(Person::compareByName, p1, p2);System.out.println("p1 排序在 p2 後: " + result);
這裡isLarge方法,除介面外,還要求傳遞兩個Person的執行個體對象。這兩個對象,被Compare介面中的compareTo方法使用。
不需要在外部調用方法中,聲明參數
再來看如下一組代碼:
Integer[] ary = {2, 8, 1, 5, 6, 3, 4};Arrays.sort(ary, (o1, o2) -> o1.compareTo(o2));Arrays.sort(ary, Integer::compareTo);
這是調用數組工具類Arrays.sort()來進行排序。
在【Arrays.sort(ary, Integer::compareTo);】中,”類執行個體方法引用”實際指代java.util.Comparator介面,介面中的靜態方法為:int compare(T o1, T o2);而這裡並沒有傳遞o1、o2參數。o1,o2的執行個體化,實際上是在sort方法內部完成的。 就好比如下樣本,
/**內部執行個體化*/public boolean isLarge(Compare<Person> c) { Person p1 = new Person("stone"); Person p2 = new Person("austin"); return c.compareTo(p1, p2);}
使用lambda和類執行個體方法引用:
isLarge((v1, v2) -> v1.compareByName(v2));//lambda expressionisLarge(Person::compareByName);//method reference
構造方法引用
現有下面的代碼:
static class Person { String name; public Person() { } public Person(String name) { this.name = name; }}public interface GetType<T> { T get(String value);}public interface GetType2<T> { T get();}public Person getPerson(String name, GetType<Person> data) { return data.get(name);}public Person getPerson(GetType2<Person> data) { return data.get();}
使用lambda和構造方法引用:
getPerson("li si", value -> new Person(value));//lambda//會調用new Person(String name) 指代GetTypegetPerson("zhang san", Person::new);getPerson(() -> new Person());//lambdagetPerson(Person::new);//會調用new Person() 指代GetType2
總結
不管是lambda運算式,還是”方法引用”,它們都指代一個僅含單一抽象方法介面的匿名內部類執行個體。使用”方法引用”後,一看錶達式,就能猜出方法引用的類別。同時配合AS,看調用方法的介面。
“方法引用”運算式的傳回值與介面中方法的傳回值一致。”方法引用”運算式所調用方法的參數,可以通過外部調用方法來傳值。如果有參數,而沒傳值,可能在外部方法內部進行了初始化,如”類執行個體方法引用”第二個樣本。
lambda運算式,是可以有一個方法體的。現在有了”方法引用”,就不用看起來那麼”混亂”了。比如:
button.setOnTouchListener((view, event)-> { if (event.getAction() == MotionEvent.ACTION_DOWN) { //do sth. return true; } else if (event.getAction() == MotionEvent.ACTION_MOVE) { //do sth. return true; } return super.onTouchEvent(event);});
只需要聲明一個方法:
private boolean handleEvent(View v, MotionEvent event) { //do sth. return true;}
如下使用”方法引用”調用:
button.setOnTouchListener(this::handleEvent);
Android 使用Java8新特性之"方法引用"