1. 程式人生 > 實用技巧 >點選就產生60秒倒計時的按鈕->點選後就會執行某操作,立刻開啟倒計時x秒,倒計時結束才能再次能夠點選。

點選就產生60秒倒計時的按鈕->點選後就會執行某操作,立刻開啟倒計時x秒,倒計時結束才能再次能夠點選。

Lambda表示式

interface Body {
    String detailed(String head);
}

public class Sample {
    @Test
   public void test_1(){
       Body b= h -> h + " No Parens!";
       System.out.println(b.detailed("1111"));
   }
}

函數語言程式設計語言操縱程式碼片段就像操作資料一樣容易。 雖然 Java 不是函式式語言,但 Java 8 Lambda 表示式和方法引用 (Method References) 允許你以函數語言程式設計。

OO(object oriented,面向物件)是抽象資料,FP(functional programming,函數語言程式設計)是抽象行為。

任何 Lambda 表示式的基本語法是:

  1. 引數。
  2. 接著 ->,可視為“產出”。
  3. -> 之後的內容都是方法體。
    • [1] 當只用一個引數,可以不需要括號 ()。 然而,這是一個特例。
    • [2] 正常情況使用括號 () 包裹引數。 為了保持一致性,也可以使用括號 () 包裹單個引數,雖然這種情況並不常見。
    • [3] 如果沒有引數,則必須使用括號 () 表示空引數列表。
    • [4] 對於多個引數,將引數列表放在括號 () 中。

到目前為止,所有 Lambda 表示式方法體都是單行。 該表示式的結果自動成為 Lambda 表示式的返回值,在此處使用 return

關鍵字是非法的。 這是 Lambda 表示式簡化相應語法的另一種方式。

[5] 如果在 Lambda 表示式中確實需要多行,則必須將這些行放在花括號中。 在這種情況下,就需要使用 return

Lambda 表示式通常比匿名內部類產生更易讀的程式碼,因此我們將在本書中儘可能使用它們。

遞迴

interface IntCall {
  int call(int arg);
}

public class RecursiveFactorial {
  static IntCall fact;
  public static void main(String[] args) {
    fact = n -> n == 0 ? 1 : n * fact.call(n - 1);
    for(int i = 0; i <= 10; i++)
      System.out.println(fact.call(i));
  }
}

方法引用

方法引用組成:類名或物件名,後面跟 :: [^4],然後跟方法名稱。

import java.util.*;

interface Callable { // [1]
  void call(String s);
}

class Describe {
  void show(String msg) { // [2]
    System.out.println(msg);
  }
}

public class MethodReferences {
  static void hello(String name) { // [3]
    System.out.println("Hello, " + name);
  }
  static class Description {
    String about;
    Description(String desc) { about = desc; }
    void help(String msg) { // [4]
      System.out.println(about + " " + msg);
    }
  }
  static class Helper {
    static void assist(String msg) { // [5]
      System.out.println(msg);
    }
  }
  public static void main(String[] args) {
    Describe d = new Describe();
    Callable c = d::show; // [6]
    c.call("call()"); // [7]

    c = MethodReferences::hello; // [8]
    c.call("Bob");

    c = new Description("valuable")::help; // [9]
    c.call("information");

    c = Helper::assist; // [10]
    c.call("Help!");
  }
}

[1] 我們從單一方法介面開始(同樣,你很快就會了解到這一點的重要性)。

[2] show() 的簽名(引數型別和返回型別)符合 Callablecall() 的簽名。

Callable介面是屬於Executor框架中的功能類,Callable介面與Runnable介面的功能類似,但提供了比Runnable更加強大的功能。

  • Callable可以在任務結束的時候提供一個返回值,Runnable無法提供這個功能
  • Callable的call方法分可以丟擲異常,而Runnable的run方法不能丟擲異常。

[3] hello() 也符合 call() 的簽名。

[4] help() 也符合,它是靜態內部類中的非靜態方法。

[5] assist() 是靜態內部類中的靜態方法。

[6] 我們將 Describe 物件的方法引用賦值給 Callable ,它沒有 show() 方法,而是 call() 方法。 但是,Java 似乎接受用這個看似奇怪的賦值,因為方法引用符合 Callablecall() 方法的簽名。

[7] 我們現在可以通過呼叫 call() 來呼叫 show(),因為 Java 將 call() 對映到 show()

[8] 這是一個靜態方法引用。

[9] 這是 [6] 的另一個版本:對已例項化物件的方法的引用,有時稱為繫結方法引用

[10] 最後,獲取靜態內部類中靜態方法的引用與 [8] 中通過外部類引用相似。