【Java新特性】Lambda表示式典型案例,你想要的的都在這兒了!!

冰河團隊發表於2020-05-06

寫在前面

不得不說,有些小夥伴的學習熱情真高,學完了Lambda表示式的語法,想來幾個典型案例再強化下。於是問冰河能否給幾個Lambda表示式的典型使用示例。於是乎,便有了這篇文章。

案例一

需求

呼叫Collections.sort()方法,通過定製排序比較兩個Employee(先比較年齡,年齡相同按姓名比較),使用Lambda表示式作為引數傳遞。

實現

這裡,我們先建立一個Employee類,為了滿足需求,我們在Employee類中定義了姓名、年齡和工資三個欄位,如下所示。

@Data
@Builder
@ToString
@NoArgsConstructor
@AllArgsConstructor
public class Employee implements Serializable {
    private static final long serialVersionUID = -9079722457749166858L;
    private String name;
    private Integer age;
    private Double salary;
}

接下來,我們在TestLambda類中定義一個成員變數employees,employees變數是一個List集合,儲存了Employee的一個列表,如下所示。

protected List<Employee> employees = Arrays.asList(
    new Employee("張三", 18, 9999.99),
    new Employee("李四", 38, 5555.55),
    new Employee("王五", 60, 6666.66),
    new Employee("趙六", 8, 7777.77),
    new Employee("田七", 58, 3333.33)
);

前期的準備工作完成了,接下來,我們就可以實現具體的業務邏輯了。

@Test
public void test1(){
    Collections.sort(employees, (e1, e2) -> {
        if(e1.getAge() == e2.getAge()){
            return e1.getName().compareTo(e2.getName());
        }
        return Integer.compare(e1.getAge(), e2.getAge());
    });
    employees.stream().forEach(System.out::println);
}

上述程式碼比較簡單,我就不贅述具體邏輯了。執行test1方法,得出的結果資訊如下所示。

Employee(name=趙六, age=8, salary=7777.77)
Employee(name=張三, age=18, salary=9999.99)
Employee(name=李四, age=38, salary=5555.55)
Employee(name=田七, age=58, salary=3333.33)
Employee(name=王五, age=60, salary=6666.66)

如果想倒敘輸出如何處理呢,只需要在將return Integer.compare(e1.getAge(), e2.getAge());修改成-return Integer.compare(e1.getAge(), e2.getAge());即可,如下所示。

@Test
public void test1(){
    Collections.sort(employees, (e1, e2) -> {
        if(e1.getAge() == e2.getAge()){
            return e1.getName().compareTo(e2.getName());
        }
        return -Integer.compare(e1.getAge(), e2.getAge());
    });
    employees.stream().forEach(System.out::println);
}

再次執行test1方法,得出的結果資訊如下所示。

Employee(name=王五, age=60, salary=6666.66)
Employee(name=田七, age=58, salary=3333.33)
Employee(name=李四, age=38, salary=5555.55)
Employee(name=張三, age=18, salary=9999.99)
Employee(name=趙六, age=8, salary=7777.77)

結果符合我們的需求。

案例二

需求

1.宣告函式式介面,介面中宣告抽象方法public String getValue(String str);

2.宣告類TestLambda,類中編寫方法使用介面作為引數,將一個字串轉換為大寫,並作為方法的返回值。

3.再將一個字串的第2個和第4個索引位置進行擷取子串。

實現

首先,建立一個函式式介面MyFunction,在MyFunction介面上加上註解@FunctionalInterface標識介面是一個函式式介面。如下所示。

@FunctionalInterface
public interface MyFunction {
    public String getValue(String str);
}

在TestLambda類中宣告stringHandler方法,引數分別為待處理的字串和函式式介面的例項,方法中的邏輯就是呼叫函式式介面的方法來處理字串,如下所示。

public String stringHandler(String str, MyFunction myFunction){
    return myFunction.getValue(str);
}

接下來,我們實現將一個字串轉換為大寫的邏輯,如下所示。

@Test
public void test2(){
    String value = stringHandler("binghe", (s) -> s.toUpperCase());
    System.out.println(value);
}

執行test2方法,得出如下的結果資訊。

BINGHE

我們再來實現字串擷取的操作,如下所示。

@Test
public void test3(){
    String value = stringHandler("binghe", (s) -> s.substring(1, 3));
    System.out.println(value);
}

注意:需求中是按照第2個和第4個索引位置進行擷取子串,字串的下標是從0開始的,所以這裡擷取字串時使用的是substring(1, 3),而不是substring(2, 4),這也是很多小夥伴容易犯的錯誤。

另外,使用上述Lambda表示式形式,可以實現字串的任意處理,並返回處理後的新字串。

執行test3方法,結果如下所示。

in

案例三

需求

1.宣告一個帶兩個泛型的函式式介面,泛型型別為<T, R>,其中,T作為引數的型別,R作為返回值的型別。

2.介面中宣告物件的抽象方法。

3.在TestLambda類中宣告方法。使用介面作為引數計算兩個long型引數的和。

4.再就按兩個long型引數的乘積。

實現

首先,我們按照需求定義函式式介面MyFunc,如下所示。

@FunctionalInterface
public interface MyFunc<T, R> {

    R getValue(T t1, T t2);
}

接下來,我們在TestLambda類中建立一個處理兩個long型資料的方法,如下所示。

public void operate(Long num1, Long num2, MyFunc<Long, Long> myFunc){
    System.out.println(myFunc.getValue(num1, num2));
}

我們可以使用下面的方法來完成兩個long型引數的和。

@Test
public void test4(){
    operate(100L, 200L, (x, y) -> x + y);
}

執行test4方法,結果如下所示。

300

實現兩個long型資料的乘積,也很簡單。

@Test
public void test5(){
    operate(100L, 200L, (x, y) -> x * y);
}

執行test5方法,結果如下所示。

20000

看到這裡,我相信很多小夥伴已經對Lambda表示式有了更深層次的理解。只要多多練習,就能夠更好的掌握Lambda表示式的精髓。

寫在最後

如果覺得文章對你有點幫助,請微信搜尋並關注「 冰河技術 」微信公眾號,跟冰河學習Java8新特性。

最後,附上Java8新特性核心知識圖,祝大家在學習Java8新特性時少走彎路。

相關文章