Java中Consumer與Supplier接口的使用及區(qū)別小結(jié)
異同分析
Consumer 和 Supplier 是 Java 8 引入的兩個重要函數(shù)式接口,位于 java.util.function 包中,用于支持函數(shù)式編程范式。
相同點
- 都是函數(shù)式接口(只有一個抽象方法)
- 都位于
java.util.function包中 - 都用于 Lambda 表達式和方法引用
- 都在 Stream API 和 Optional 類中廣泛使用
不同點
| 特性 | Consumer | Supplier |
|---|---|---|
| 方法簽名 | void accept(T t) | T get() |
| 參數(shù) | 接受一個輸入?yún)?shù) | 無輸入?yún)?shù) |
| 返回值 | 無返回值 | 返回一個值 |
| 主要用途 | 消費數(shù)據(jù) | 提供數(shù)據(jù) |
| 類比 | 方法中的參數(shù) | 方法中的返回值 |
詳細分析與使用場景
Consumer 接口
Consumer 表示接受單個輸入?yún)?shù)但不返回結(jié)果的操作。
import java.util.function.Consumer;
import java.util.Arrays;
import java.util.List;
public class ConsumerExample {
public static void main(String[] args) {
// 基本用法
Consumer<String> printConsumer = s -> System.out.println(s);
printConsumer.accept("Hello Consumer!");
// 方法引用方式
Consumer<String> methodRefConsumer = System.out::println;
methodRefConsumer.accept("Hello Method Reference!");
// 集合遍歷中的應(yīng)用
List<String> names = Arrays.asList("Alice", "Bob", "Charlie");
names.forEach(printConsumer);
// andThen 方法組合多個 Consumer
Consumer<String> upperCaseConsumer = s -> System.out.println(s.toUpperCase());
Consumer<String> decoratedConsumer = s -> System.out.println("*** " + s + " ***");
Consumer<String> combinedConsumer = upperCaseConsumer.andThen(decoratedConsumer);
combinedConsumer.accept("functional interface");
// 在 Optional 中的使用
java.util.Optional<String> optional = java.util.Optional.of("Present");
optional.ifPresent(combinedConsumer);
}
}
Consumer 的使用場景:
- 遍歷集合元素并執(zhí)行操作
- 處理數(shù)據(jù)并產(chǎn)生副作用(如打印、保存到數(shù)據(jù)庫)
- 在 Optional 中處理可能存在的值
- 組合多個操作形成處理鏈
Supplier 接口
Supplier 表示一個供應(yīng)商,不需要傳入?yún)?shù)但返回一個值。
import java.util.function.Supplier;
import java.util.List;
import java.util.Random;
import java.util.stream.Stream;
public class SupplierExample {
public static void main(String[] args) {
// 基本用法
Supplier<String> stringSupplier = () -> "Hello from Supplier!";
System.out.println(stringSupplier.get());
// 方法引用方式
Supplier<Double> randomSupplier = Math::random;
System.out.println("Random number: " + randomSupplier.get());
// 對象工廠
Supplier<List<String>> listSupplier = () -> java.util.Arrays.asList("A", "B", "C");
System.out.println("List from supplier: " + listSupplier.get());
// 延遲計算/初始化
Supplier<ExpensiveObject> expensiveObjectSupplier = () -> {
System.out.println("Creating expensive object...");
return new ExpensiveObject();
};
System.out.println("Supplier created but no object yet...");
// 只有在調(diào)用 get() 時才會創(chuàng)建對象
ExpensiveObject obj = expensiveObjectSupplier.get();
// 在 Stream 中生成無限流
Supplier<Integer> randomIntSupplier = () -> new Random().nextInt(100);
Stream.generate(randomIntSupplier)
.limit(5)
.forEach(System.out::println);
// 在 Optional 中作為備選值
java.util.Optional<String> emptyOptional = java.util.Optional.empty();
String value = emptyOptional.orElseGet(() -> "Default from supplier");
System.out.println("Value from empty optional: " + value);
}
static class ExpensiveObject {
ExpensiveObject() {
// 模擬耗時操作
try { Thread.sleep(1000); } catch (InterruptedException e) {}
}
}
}
Supplier 的使用場景:
- 延遲初始化或延遲計算
- 提供配置或默認值
- 生成測試數(shù)據(jù)或模擬對象
- 在 Optional 中提供備選值
- 創(chuàng)建對象工廠
- 實現(xiàn)惰性求值模式
實際應(yīng)用示例
下面是一個結(jié)合使用 Consumer 和 Supplier 的示例:
import java.util.function.Consumer;
import java.util.function.Supplier;
import java.util.logging.Logger;
public class CombinedExample {
private static final Logger logger = Logger.getLogger(CombinedExample.class.getName());
public static void main(String[] args) {
// 創(chuàng)建一個數(shù)據(jù)處理器,結(jié)合了 Supplier 和 Consumer
processData(
() -> { // Supplier - 提供數(shù)據(jù)
// 模擬從數(shù)據(jù)庫或API獲取數(shù)據(jù)
return new String[] {"Data1", "Data2", "Data3"};
},
data -> { // Consumer - 處理數(shù)據(jù)
for (String item : data) {
System.out.println("Processing: " + item);
}
},
error -> { // Consumer - 錯誤處理
logger.severe("Error occurred: " + error.getMessage());
}
);
}
public static <T> void processData(Supplier<T> dataSupplier,
Consumer<T> dataProcessor,
Consumer<Exception> errorHandler) {
try {
T data = dataSupplier.get(); // 從Supplier獲取數(shù)據(jù)
dataProcessor.accept(data); // 用Consumer處理數(shù)據(jù)
} catch (Exception e) {
errorHandler.accept(e); // 用Consumer處理錯誤
}
}
}
總結(jié)
- Consumer 用于表示接受輸入并執(zhí)行操作但不返回結(jié)果的函數(shù),常見于需要處理數(shù)據(jù)并產(chǎn)生副作用的場景
- Supplier 用于表示無需輸入但返回結(jié)果的函數(shù),常見于延遲計算、提供數(shù)據(jù)和工廠模式場景
- 兩者都是函數(shù)式編程中的重要構(gòu)建塊,可以組合使用創(chuàng)建靈活的數(shù)據(jù)處理管道
- 在 Stream API、Optional 和現(xiàn)代 Java 框架中廣泛應(yīng)用
理解這兩個接口的差異和適用場景有助于編寫更簡潔、更表達力的 Java 代碼,特別是在使用 Stream API 和函數(shù)式編程范式時。
到此這篇關(guān)于Java中Consumer與Supplier接口的使用及區(qū)別小結(jié)的文章就介紹到這了,更多相關(guān)Java Consumer與Supplier接口內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Mybatis-plus配置多數(shù)據(jù)源,連接多數(shù)據(jù)庫方式
這篇文章主要介紹了Mybatis-plus配置多數(shù)據(jù)源,連接多數(shù)據(jù)庫方式,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教2024-06-06
詳解SpringBoot中自定義starter的開發(fā)與使用
starter是SpringBoot中非常重要的一個機制,他是基于約定優(yōu)于配置的思想所衍生出來的,本文主要介紹了SpringBoot中自定義starter的開發(fā)與使用,感興趣的可以了解下2023-09-09
SpringBoot整合Redis實現(xiàn)刷票過濾功能
隨著互聯(lián)網(wǎng)的不斷發(fā)展,網(wǎng)站或APP的用戶流量增加,也衍生出了一些惡意刷量等問題,給數(shù)據(jù)分析及運營帶來極大的困難,所以本文使用SpringBoot和Redis實現(xiàn)一個刷票過濾功能,需要的可以參考一下2023-06-06

