[Java] 17.1. lambda & 匿名類別

lambda將方法變為一個個方便使用的運算函式,其背後的原因是實現匿名類別。

 

image/svg+xml17.1.lambda 與匿名類別 - lambda & Anonymous class class Employee extends Person{ String employeeID; int salary; public Employee( String pID, String pName , int pAge, String pGender , String pEmployeeID, int pSalary){ id = pID; name = pName; age = pAge; gender = pGender; employeeID = pEmployeeID; salary = pSalary; } } import java.util.*; class Main{ public static void main( String [] args){ Employee e1 = new Employee ( "K12345678" , “Jack" , 20 , " 男⽣ " , "048679" , 40000 ); Employee e2 = new Employee ( "K00000000" , “Eric" , 25 , " 男⽣ " , "041121" , 45000 ); Employee e3 = new Employee ( "K11111111" , “Mary" , 18 , " 女⽣ " , "050021" , 30000 ); Employee e4 = new Employee ( "K22222222" , “Jack" , 19 , " 男⽣ " , "051212" , 42000 ); List l = new ArrayList (); l.add ( e1 ); l.add ( e2 ); l.add ( e3 ); l.add ( e4 ); Collections.sort ( l , new Comparator () { public int compare ( Object o1, Object o2) { Employee emp1 = (Employee) o1; Employee emp2 = (Employee) o2; return emp1.name.compareTo(emp2.name); } } ); for ( Object o : l){ Employee e = (Employee)o; System.out.println(e.name); } } } import java.util.*; class Main{ public static void main( String [] args){ Employee e1 = new Employee ( "K12345678" , “Jack" , 20 , " 男⽣ " , "048679" , 40000 ); Employee e2 = new Employee ( "K00000000" , “Eric" , 25 , " 男⽣ " , "041121" , 45000 ); Employee e3 = new Employee ( "K11111111" , “Mary" , 18 , " 女⽣ " , "050021" , 30000 ); Employee e4 = new Employee ( "K22222222" , “Jack" , 19 , " 男⽣ " , "051212" , 42000 ); List l = new ArrayList (); l.add ( e1 ); l.add ( e2 ); l.add ( e3 ); l.add ( e4 ); Collections.sort ( l , new Comparator () { public int compare ( Object o1, Object o2) { Employee emp1 = (Employee) o1; Employee emp2 = (Employee) o2; return emp1.name.compareTo(emp2.name); } } ); for ( Object o : l){ Employee e = (Employee)o; System.out.println(e.name); } Collections.sort ( l , ( Object o1, Object o2) -> { Employee emp1 = (Employee) o1; Employee emp2 = (Employee) o2; return emp1.name.compareTo(emp2.name) ; } ); for ( Object o : l){ Employee e = (Employee)o; System.out.println(e.name); } } } import java.util.*; class Main{ public static void main( String [] args){ Employee e1 = new Employee ( "K12345678" , “Jack" , 20 , " 男⽣ " , "048679" , 40000 ); Employee e2 = new Employee ( "K00000000" , “Eric" , 25 , " 男⽣ " , "041121" , 45000 ); Employee e3 = new Employee ( "K11111111" , “Mary" , 18 , " 女⽣ " , "050021" , 30000 ); Employee e4 = new Employee ( "K22222222" , “Jack" , 19 , " 男⽣ " , "051212" , 42000 ); List l = new ArrayList(); l.add(e1); l.add(e2); l.add(e3); l.add(e4); Collections.sort( l , ( Object o1, Object o2) -> { Employee emp1 = (Employee) o1; Employee emp2 = (Employee) o2; return emp1.name.compareTo(emp2.name); } ); for ( Object o : l){ Employee e = (Employee)o; System.out.println(e.name); } } } import java.util.*; class Main{ public static void main( String [] args){ Employee e1 = new Employee ( "K12345678" , “Jack" , 20 , " 男⽣ " , "048679" , 40000 ); Employee e2 = new Employee ( "K00000000" , “Eric" , 25 , " 男⽣ " , "041121" , 45000 ); Employee e3 = new Employee ( "K11111111" , “Mary" , 18 , " 女⽣ " , "050021" , 30000 ); Employee e4 = new Employee ( "K22222222" , “Jack" , 19 , " 男⽣ " , "051212" , 42000 ); List l = new ArrayList(); l.add(e1); l.add(e2); l.add(e3); l.add(e4); Comparator nameComparator = ( Object o1, Object o2) -> { Employee emp1 = (Employee) o1; Employee emp2 = (Employee) o2; return emp1.name.compareTo(emp2.name) ; } Collections.sort ( l , nameComparator ); for ( Object o : l){ Employee e = (Employee)o; System.out.println(e.name); } } } J17_1_1 Employee.java 2. 建立 4 個員⼯物件並放入 ArrayList J17_1_1 Main.java 3. 雖然使⽤匿名類別快速的建立以姓名排序和年齡排序的比較器 Comparator ,即便使⽤了匿名類別的技巧但還是寫了⼀⼤段程 式,有沒有更簡化的⽅式快速實現不同的比較器以進⾏排序呢 ? 1. 建立 4 個員⼯物件並放入 ArrayList 2. 這是原先使⽤匿名類別建立的姓名比較器。 J17_1_2 Main.java 3. lambda 在數學上就是⼀個函式的意思,使⽤ lambda 建立姓名比較器時,你會發現你只需寫下⽅法 的部份即可,並不需要 new ⼀個匿名的 Comparator 4. 不同於⼀般的⽅法的是不需 要⽅法名字,之後寫下參數。 5. 接著是⼀個箭頭 (->) 指向⼀個 ⼤括號 ({}) ,即⽅法的實體部份。 6. 當然,你也不需定義回傳值的型別,編譯器會⾃動 透過 return 回傳的值判斷回傳的型別, CompareTo() ⽅法會回傳 int ,因此推論為 int 型別。 7. 整體⽽⾔它就像在寫⼀個函式,簡簡單單。 什麼是函式 ? 在過去的程式語⾔中 ( c) ⽅法是可以獨立在類別之外的,⽽這 個獨立存在的⽅法即是函式。函式就是不在類別中的⽅法,⽅法是物件導向的 術語,⽅法即是存在於類別上的函式。 J17_1_3 Main.java 1. 為何可以直接寫⼀個匿名函式呢 ? Java 不是 以類別為基礎然後才有⽅法嗎 ? 這是怎麼回事 ? J17_1_4 Main.java 1. lambda 最後還是會建立⼀個匿名類別,只是編譯器幫你做了這件事,有趣的 是,編譯器可以透過變數的型別,和實作的⽅法決定要建立哪個介⾯的匿名類別。 2. ⾸先,從變數得知是 Comparator 介⾯的型別。 3. 再來是 lambda 函式的格式完全符合它的⽅法格式: 有兩個 Object 參數、 return 的回傳值為 int 4. 在此將 lambda 建立的匿名物件放在 nameComparator 變數 中,這也證明了 lambda 其實是在匿名物件。 1. lambda 最後還是會建立⼀個匿名 類別,比如實作 Comparator 介⾯。 匿名實作排序的演算法還是太⿇煩了, 有更簡單的⽅式嗎 ? 1. 員⼯類別 (Employee) lambda ,快速建立員⼯的排序函式 Java 不是以類別為基礎嗎 ? 為何寫⼀個函式就可以運作了 ? 真是神奇 寫起來像函式, 但實際上是實作 Comparator 的匿名類別

留言