這篇會整理的是,在傳統語法下及 Lambda 語法,以排序為例進行說明:
在開始說明前,先定義一個類別如下:
程式一開始會進建立一個命名為 world 的 List
- @Data
- public class Country implements Serializable {
- private String name; //國名
- private String capital; //首都
- private String area; //位於那個洲?
- private int gdp; //人均GDP
- private int population; //人口總數
- public Country() { }
- public Country(String name, String capital, String area, int gdp, int population) {
- this.name = name;
- this.capital = capital;
- this.area = area;
- this.gdp = gdp;
- this.population = population;
- }
- }
下面的例子就用人口數來排序 world 裡的國家。
- List<Country> world = Arrays.asList(
- new Country("Taiwan", "Taipei", "Asia", 24500, 23500000),
- new Country("Korea", "Seoul", "Asia", 31430, 51709098),
- new Country("Philippines", "Manila", "Asia", 3117, 107225000),
- new Country("Nederland", "Amsterdam", "Europe", 53106, 17291000),
- new Country("Canada", "Ottawa", "America", 47931, 37281000),
- new Country("Australia", "Canberra", "Oceania", 51592, 25220000)
- );
- 定義實作 Comparator 介面的類別
- private class CountryComparator implements Comparator<Country> {
- @Override
- public int compare(Country c1, Country c2) {
- return c1.getPopulation() - c2.getPopulation();
- }
- }
- world.sort(new CountryComparator());
- 定義實作 Comparator 介面的匿名類別
- world.sort(
- new Comparator<Country>() {
- @Override
- public int compare(Country c1, Country c2) {
- return c1.getPopulation() - c2.getPopulation();
- }
- });
- 使用 Lambda
- world.sort((c1, c2) -> c1.getPopulation() - c2.getPopulation());
- 使用「方法引用」 這是 Lambda 的語法糖,這裡假設我們有靜態導入 java.util.Comparator.comparing (import static java.util.Comparator.comparing)。
- world.sort(comparing(Country::getPopulation));
使用上述的類別規範了比較的方式,程式會如下:
這兩種寫法,都是 Java 7 以前的寫法,當這個用來比較的類別很短,又只會使用一次,採用匿名類別可讀性會比較高。
程式怎麼會變得這麼簡單,而且清楚明白,Lambda 怎麼辦到的? Lambda 的使用有一些限制,sort 接受的 Comparator 介面只有一個 method,這是它的重要限制之一! 因為只有一個 method,Lambda expression 就看的出來是要傳入 c1、c2 兩個 Country 類別的物件進入 compare() method,compare() method 在這裡實作為 return c1.getPopulation() - c2.getPopulation()。
直接指明要調用 Country 裡的 getPopulation() 的值進行比較。這裡有個疑問,怎麼 Comparator 類別又多出了 comparing 這個 method 了? 而且這個 method 還不只是定義了介面,還實作了 method ! 這是 Java 8 之後才有的,interface 裡也可以實作 method,但是,因為裡面只有一個未實作的 method,仍是合乎 Lambda 的限制,Lambda 知道要使用那個 method。
- 有興趣的話,再觀察一下 Comparator 的原始碼,多了不少 static method,上面只比較人口數,事實上我們可以複合比較,如下:
- world.sort(
- comparing(Country::getArea).thenComparing(Country::getPopulation)
- );
沒有留言:
張貼留言