點選就產生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] 如果沒有引數,則必須使用括號
()
表示空引數列表。 - [4] 對於多個引數,將引數列表放在括號
()
中。
- [1] 當只用一個引數,可以不需要括號
到目前為止,所有 Lambda 表示式方法體都是單行。 該表示式的結果自動成為 Lambda 表示式的返回值,在此處使用 return
[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()
的簽名(引數型別和返回型別)符合 Callable 的 call()
的簽名。
Callable介面是屬於Executor框架中的功能類,Callable介面與Runnable介面的功能類似,但提供了比Runnable更加強大的功能。
- Callable可以在任務結束的時候提供一個返回值,Runnable無法提供這個功能
- Callable的call方法分可以丟擲異常,而Runnable的run方法不能丟擲異常。
[3] hello()
也符合 call()
的簽名。
[4] help()
也符合,它是靜態內部類中的非靜態方法。
[5] assist()
是靜態內部類中的靜態方法。
[6] 我們將 Describe 物件的方法引用賦值給 Callable ,它沒有 show()
方法,而是 call()
方法。 但是,Java 似乎接受用這個看似奇怪的賦值,因為方法引用符合 Callable 的 call()
方法的簽名。
[7] 我們現在可以通過呼叫 call()
來呼叫 show()
,因為 Java 將 call()
對映到 show()
。
[8] 這是一個靜態方法引用。
[9] 這是 [6] 的另一個版本:對已例項化物件的方法的引用,有時稱為繫結方法引用。
[10] 最後,獲取靜態內部類中靜態方法的引用與 [8] 中通過外部類引用相似。