Java - 函數式介面
你好,未來的Java開發者!今天,我們將進入Java中函數式介面的精彩世界。如果你是編程新手,不必擔心;我會一步一步引導你了解這個概念,就像我過去幾年教學中對無數學生所做的那樣。所以,來一杯咖啡(或你最喜歡的飲料),我們一起深入探討吧!
函數式介面是什麼?
想像一下,你在一個派對上,被分配的角色是DJ。你的工作很簡單:播放音樂。你不需要擔心提供食物或裝飾場地。在Java中,函數式介面就像那個DJ——它有一個特定的任務要完成,而且做得很好。
在技術術語中,函數式介面是一個包含正好一個抽象方法的介面。它可以有其他方法,但這些方法必須是默認或靜态方法。單一的抽象方法賦予了函數式介面其“函數式”的本質。
示例1:一個簡單的函數式介面
@FunctionalInterface
interface Greeter {
void greet(String name);
}
在這個示例中,Greeter
是一個函數式介面。它只有一個抽象方法greet
,該方法接受一個String參數並不返回任何東西(void)。
@FunctionalInterface注解
你可能已經注意到我們示例中的@FunctionalInterface
注解。這就像在我們的介面上貼上“DJ”徽章。它告訴Java,“嘿,這個介面應該是函數式的!”如果我們不小心添加了另一個抽象方法,Java會給我們一個錯誤,幫助我們保持介面的函數式本質。
使用函數式介面
現在我們知道了函數式介面是什麼,我們來看看如何使用它們。函數式介面的一個最酷的地方是我们可以用它們與lambda表達式一起使用,這些表達式就像是编写方法的簡略方式。
示例2:將函數式介面與Lambda表達式一起使用
public class GreeterTest {
public static void main(String[] args) {
Greeter friendlyGreeter = (name) -> System.out.println("你好," + name + "! 你怎麼樣?");
friendlyGreeter.greet("Alice");
Greeter formalGreeter = (name) -> System.out.println("下午好," + name + "。希望你一切安好。");
formalGreeter.greet("史密斯先生");
}
}
在這個示例中,我們使用Greeter
介面創建了兩個不同的歡迎者。lambda表達式(name) -> ...
即時實現了greet
方法。這就像為兩個不同的派對雇傭兩個不同的DJ一樣!
當你運行這段代碼時,你會看到:
你好,Alice! 你怎麼樣?
下午好,史密斯先生。希望你一切安好。
Java中的函數式介面類型
Java提供了許多內置的函數式介面,使我們的生活更加輕鬆。讓我們看看一些最常使用的:
1. Predicate
Predicate<T>
介面用於一個參數的布爾值函數。它就像一個可以回答是或不是的問題。
import java.util.function.Predicate;
public class PredicateExample {
public static void main(String[] args) {
Predicate<Integer> isAdult = age -> age >= 18;
System.out.println("20是成年年齡嗎? " + isAdult.test(20));
System.out.println("15是成年年齡嗎? " + isAdult.test(15));
}
}
這將輸出:
20是成年年齡嗎? true
15是成年年齡嗎? false
2. Function<T,R>
Function<T,R>
介面表示一個接受一個參數並生成結果的函數。它就像一臺將某物投入並產生其他東西的機器。
import java.util.function.Function;
public class FunctionExample {
public static void main(String[] args) {
Function<String, Integer> stringLength = str -> str.length();
System.out.println("'Hello'的長度: " + stringLength.apply("Hello"));
System.out.println("'Java is awesome'的長度: " + stringLength.apply("Java is awesome"));
}
}
這將輸出:
'Hello'的長度: 5
'Java is awesome'的長度: 16
3. Consumer
Consumer<T>
介面表示一個接受單個輸入參數並返回無結果的操作。它就像一個黑洞,消耗數據但不產生任何東西。
import java.util.function.Consumer;
public class ConsumerExample {
public static void main(String[] args) {
Consumer<String> printer = message -> System.out.println("列印: " + message);
printer.accept("你好,函數式介面!");
printer.accept("Java很有趣!");
}
}
這將輸出:
列印: 你好,函數式介面!
列印: Java很有趣!
4. Supplier
Supplier<T>
介面表示結果的供應商。它不接受參數但產生一個值。它就像一臺不需要你放入東西就能給你一些東西的售貨機。
import java.util.function.Supplier;
import java.util.Random;
public class SupplierExample {
public static void main(String[] args) {
Supplier<Integer> randomNumberSupplier = () -> new Random().nextInt(100);
System.out.println("隨機數字: " + randomNumberSupplier.get());
System.out.println("另一個隨機數字: " + randomNumberSupplier.get());
}
}
這將輸出兩個0到99之間的隨機數字,例如:
隨機數字: 42
另一個隨機數字: 73
Java 8之前存在的函數式介面
在Java 8引入函數式介面概念之前,Java有一些符合定義的介面。這些主要用於事件處理和並發編程。讓我們看看一些示例:
1. Runnable
Runnable
介面自Java早期時代以來就存在。它通常用於創建線程。
public class RunnableExample {
public static void main(String[] args) {
Runnable helloRunnable = () -> System.out.println("來自線程的問候!");
new Thread(helloRunnable).start();
}
}
這將輸出:
來自線程的問候!
2. Comparator
Comparator
介面用於定義對象的自定義排序。
import java.util.Arrays;
import java.util.Comparator;
public class ComparatorExample {
public static void main(String[] args) {
String[] names = {"Alice", "Bob", "Charlie", "David"};
Comparator<String> lengthComparator = (s1, s2) -> s1.length() - s2.length();
Arrays.sort(names, lengthComparator);
System.out.println("按長度排序: " + Arrays.toString(names));
}
}
這將輸出:
按長度排序: [Bob, Alice, David, Charlie]
結論
恭喜你!你剛剛走出了Java中函數式介面的第一步。我們已經介绍了它們是什麼、如何使用它們,並查看了一些常見類型。請記住,函數式介面就像你Java工具箱中的專用工具。它們幫助你编写更乾淨、表達性更强的代碼。
隨著你繼續Java之旅,你會發現函數式介面的用處越來越多。當涉及到流和集合時,它們尤其強大,這將在我們未來的課程中進行講解。
繼續練習,保持好奇心,最重要的是,編程愉快!Java是一門廣闊且激動人心的語言,你已經在掌握它的道路上邁出了堅實的一步。直到下次,編程愉快!
Credits: Image by storyset