1. 程式人生 > >Java8 Lambda表示式之比較器

Java8 Lambda表示式之比較器

在這個例子中,我將向你展示如何使用Java8的lambda表示式寫的比較器排序列表。

  1. 經典Comparator例子
Comparator<Developer> byName = new Comparator<Developer>() {
    @Override
    public int compare(Developer o1, Developer o2) {
        return o1.getName().compareTo(o2.getName());
    }
};
  1. Lambda表示式方式
Comparator<Developer> byName =
(Developer o1, Developer o2)->o1.getName().compareTo(o2.getName());

1. 使用Lambda排序

這個例子使用年齡比較Developer物件,通常你使用Collections.sort並且通過一個匿名函式實現Comparator

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
public class TestSorting { public static void main(String[] args) { List<Developer> listDevs = getDevelopers(); System.out.println("Before Sort"); for (Developer developer : listDevs) { System.out.println(developer); } //sort by age
Collections.sort(listDevs, new Comparator<Developer>() { @Override public int compare(Developer o1, Developer o2) { return o1.getAge() - o2.getAge(); } }); System.out.println("After Sort"); for (Developer developer : listDevs) { System.out.println(developer); } } private static List<Developer> getDevelopers() { List<Developer> result = new ArrayList<Developer>(); result.add(new Developer("mkyong", new BigDecimal("70000"), 33)); result.add(new Developer("alvin", new BigDecimal("80000"), 20)); result.add(new Developer("jason", new BigDecimal("100000"), 10)); result.add(new Developer("iris", new BigDecimal("170000"), 55)); return result; } }

輸出

Before Sort
Developer [name=mkyong, salary=70000, age=33]
Developer [name=alvin, salary=80000, age=20]
Developer [name=jason, salary=100000, age=10]
Developer [name=iris, salary=170000, age=55]

After Sort
Developer [name=jason, salary=100000, age=10]
Developer [name=alvin, salary=80000, age=20]
Developer [name=mkyong, salary=70000, age=33]
Developer [name=iris, salary=170000, age=55]

當排序的需求要更改時,你需要通過一個新的Comparator比較器:

//sort by age
Collections.sort(listDevs, new Comparator<Developer>() {
    @Override
    public int compare(Developer o1, Developer o2) {
        return o1.getAge() - o2.getAge();
    }
});

//sort by name  
Collections.sort(listDevs, new Comparator<Developer>() {
    @Override
    public int compare(Developer o1, Developer o2) {
        return o1.getName().compareTo(o2.getName());
    }
});
            
//sort by salary
Collections.sort(listDevs, new Comparator<Developer>() {
    @Override
    public int compare(Developer o1, Developer o2) {
        return o1.getSalary().compareTo(o2.getSalary());
    }
});     

上面的程式碼可以工作,但是,你認為建立一個類只是因為你想改變一個單一的程式碼,不覺得有點奇怪嗎?

2. 使用Lambda排序

在Java8中,List支援sort方法,不需要使用Collections.sort

//List.sort() since Java 8
listDevs.sort(new Comparator<Developer>() {
    @Override
    public int compare(Developer o1, Developer o2) {
        return o2.getAge() - o1.getAge();
    }
}); 

Lambda表示式示例:

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;

public class TestSorting {

    public static void main(String[] args) {

        List<Developer> listDevs = getDevelopers();
        
        System.out.println("Before Sort");
        for (Developer developer : listDevs) {
            System.out.println(developer);
        }
        
        System.out.println("After Sort");
        
        //lambda here!
        listDevs.sort((Developer o1, Developer o2)->o1.getAge()-o2.getAge());
    
        //java 8 only, lambda also, to print the List
        listDevs.forEach((developer)->System.out.println(developer));
    }

    private static List<Developer> getDevelopers() {

        List<Developer> result = new ArrayList<Developer>();

        result.add(new Developer("mkyong", new BigDecimal("70000"), 33));
        result.add(new Developer("alvin", new BigDecimal("80000"), 20));
        result.add(new Developer("jason", new BigDecimal("100000"), 10));
        result.add(new Developer("iris", new BigDecimal("170000"), 55));
        
        return result;

    }
    
}

輸出

Before Sort
Developer [name=mkyong, salary=70000, age=33]
Developer [name=alvin, salary=80000, age=20]
Developer [name=jason, salary=100000, age=10]
Developer [name=iris, salary=170000, age=55]

After Sort
Developer [name=jason, salary=100000, age=10]
Developer [name=alvin, salary=80000, age=20]
Developer [name=mkyong, salary=70000, age=33]
Developer [name=iris, salary=170000, age=55]

3. 更多Lambda表示式例子

3.1 根據年齡排序

//sort by age
Collections.sort(listDevs, new Comparator<Developer>() {
    @Override
    public int compare(Developer o1, Developer o2) {
        return o1.getAge() - o2.getAge();
    }
});

//lambda
listDevs.sort((Developer o1, Developer o2)->o1.getAge()-o2.getAge());

//lambda, valid, parameter type is optional
listDevs.sort((o1, o2)->o1.getAge()-o2.getAge());

3.2 根據姓名排序

//sort by name
Collections.sort(listDevs, new Comparator<Developer>() {
    @Override
    public int compare(Developer o1, Developer o2) {
        return o1.getName().compareTo(o2.getName());
    }
});
    
//lambda
listDevs.sort((Developer o1, Developer o2)->o1.getName().compareTo(o2.getName()));      

//lambda
listDevs.sort((o1, o2)->o1.getName().compareTo(o2.getName()));

3.3 根據薪水排序

//sort by salary
Collections.sort(listDevs, new Comparator<Developer>() {
    @Override
    public int compare(Developer o1, Developer o2) {
        return o1.getSalary().compareTo(o2.getSalary());
    }
});             

//lambda
listDevs.sort((Developer o1, Developer o2)->o1.getSalary().compareTo(o2.getSalary()));

//lambda
listDevs.sort((o1, o2)->o1.getSalary().compareTo(o2.getSalary()));

3.4 排序反轉
3.4.1 使用lambda表示式對薪水進行排序

Comparator<Developer> salaryComparator = (o1, o2)->o1.getSalary().compareTo(o2.getSalary());
listDevs.sort(salaryComparator);

輸出

Developer [name=mkyong, salary=70000, age=33]
Developer [name=alvin, salary=80000, age=20]
Developer [name=jason, salary=100000, age=10]
Developer [name=iris, salary=170000, age=55]

3.4.2 使用lambda表示式對薪水進行反轉排序

Comparator<Developer> salaryComparator = (o1, o2)->o1.getSalary().compareTo(o2.getSalary());
listDevs.sort(salaryComparator.reversed());

輸出:

Developer [name=iris, salary=170000, age=55]
Developer [name=jason, salary=100000, age=10]
Developer [name=alvin, salary=80000, age=20]
Developer [name=mkyong, salary=70000, age=33]

參考資料: