1. 程式人生 > >3分鐘入門lambda表示式

3分鐘入門lambda表示式

本節是lambda表示式的一個入門課,講解的同時配有練習demo

前言什麼是lambda表示式?基礎語法函式式介面自己實現一個函式式介面jdk提供的函式式介面ConsumersupplierfunctionPredicate其他場景

前言

  lambda表示式是java8推出的一個新特性。標誌著從jdk1.8開始,java正式支援函數語言程式設計。使用lambda表示式可以用簡潔流暢的程式碼完成一個功能,這也在一定程度上,可以減輕了java一直為人詬病的程式碼簡潔性問題。


什麼是lambda表示式?

  lambda表示式可以簡單理解為一段可以傳遞的程式碼,核心思想是將面向物件中傳遞資料變為傳遞行為。下面舉一個編寫執行緒的例子。

1Runnable runnable = new Runnable() {
2  @Override
3  public void run() {
4    System.out.println("hello lambda");
5  }
6};

  這裡使用的是匿名內部類的方式。匿名內部類實現的也是將程式碼作為資料傳遞,不過使用匿名內部類還是不夠簡潔,那麼使用lambda表示式的程式碼是什麼樣的呢?

1Runnable runnable = () -> System.out.println("hello lambda");

  我們可以看到使用lambda表示式實現起來非常的簡單,只需要一行程式碼即可,接下來我們就試著分析一下這段程式碼。


基礎語法


  我們可以將lambda表示式整體看作是一個函式,()存放的是函式的運算元 ->指向的是函式的邏輯,可以用{}包裹起來。

 


函式式介面

  我們可以看到上述的示例程式碼,lambda表示式的引用變數是一個runnable型別,事實上,java為我們提供了多種變數型別供我們選擇,這些型別我們稱之為函式式介面。

  函式式介面是隻有一個方法的介面,用作lambda表示式的型別。比如我們之前提到的Runnable介面

 1@FunctionalInterface
2public interface Runnable {
3    /**
4     * When an object implementing interface <code>Runnable</code> is used
5     * to create a thread, starting the thread causes the object's
6     * <code>run</code> method to be called in that separately executing
7     * thread.
8     * <p>
9     * The general contract of the method <code>run</code> is that it may
10     * take any action whatsoever.
11     *
12     * @see     java.lang.Thread#run()
13     */
14    public abstract void run();
15}

  我們可以看到interface上一個註解@FunctionInterface,它的作用是告訴編譯器這個介面是一個函式式介面。


自己實現一個函式式介面

  我們可以自己實現一個函式式介面,判斷資料的資料是否合法

 1/**
2 * 自定義函式數介面
3 *
4 * @author jialin.li
5 * @date 2020-03-18 14:22
6 */
7@FunctionalInterface
8public interface CustomFunctionInterface<T> {
9    boolean legal(T t);
10}

測試方法:

 1/**
2 * 測試.
3 * 
4 * @author jialin.li
5 * @date 2020-03-18 14:23
6 */
7public class Test {
8
9    public boolean legal(int value, CustomFunctionInterface<Integer> functionInterface){
10        return functionInterface.legal(value);
11    }
12
13    public static void main(String[] args) {
14        System.out.println(new Test().legal(-8, (x) -> x >= 0));
15    }
16}

測試結果:

1false

jdk提供的函式式介面

  jdk在java.util.function中為我們提供了非常豐富的函式式介面,大致可以分為4類:


  接下來我們會針對這四種不同的介面,給出相應的demo,你也可以先看題目,自己嘗試寫一下

 

Consumer

將輸入的10進位制數,轉換為2進位制數輸出

1public void toBinaryString(int value, Consumer<Integer> consumer){
2    consumer.accept(value);
3}
4
5public static void main(String[] args) {
6    new Test().toBinaryString(15, (x) -> System.out.println(Integer.toBinaryString(x)));
7}

supplier

生成n個隨機數100以內的隨機數,以陣列的形式返回

 1public int[] getRandomArr(int n, Supplier<Integer> supplier) {
2    int[] arr = new int[n];
3    for (int i = 0; i < n; i++) {
4        arr[i] = supplier.get();
5    }
6    return arr;
7}
8
9public static void main(String[] args) {
10    int[] arr = new Test().getRandomArr(10, () -> new Random().nextInt(100));
11    System.out.println(Arrays.toString(arr));
12}

function

生成一個[1,n]組成的階乘陣列,例如輸入3,返回[1,4,9]

 1public int[] getFactorialArr(int n, Function<Integer,Integer> function) {
2    int[] arr = new int[n];
3    for (int i = 1; i <= n; i++) {
4        arr[i - 1] = function.apply(i);
5    }
6    return arr;
7}
8
9public static void main(String[] args) {
10    int[] arr = new Test().getFactorialArr(10, (x) -> x*x);
11    System.out.println(Arrays.toString(arr));
12}

Predicate

判斷一個數是否是偶數

1public boolean isEven(int n, Predicate<Integer> predicate) {
2    return predicate.test(n);
3}
4
5public static void main(String[] args) {
6    boolean isEven = new Test().isEven(1102, (x) -> (x % 2 == 0));
7    System.out.println(isEven);
8}

其他場景

  除了上述的4個介面,java.util.function中還有許多其他的介面,可以實現各種功能。比如實現2個數的加法運算:

1public static void main(String[] args) {
2    BinaryOperator<Integer> binaryOperator = Integer::sum;
3    System.out.println(binaryOperator.apply(1, 3));
4}

  實現List遍歷:

1public static void main(String[] args) {
2    List<String> list = new ArrayList<>(Arrays.asList("java", "python", "go", "sql"));
3    list.forEach(System.out::println);
4}

  更多場景還請您去探索,感受函數語言程式設計的魅力吧

  最後,期待您的訂閱和點贊,專欄每週都會更新,希望可以和您一起進步,同時也期待您的批評與指正!