Java Supplier和Consumer接口使用解讀
Supplier
在Java中,Supplier接口是一個(gè)重要的函數(shù)式接口,它屬于java.util.function包,Supplier通常用于延遲計(jì)算或生成值的場(chǎng)景。
Supplier接口是一個(gè)泛型接口,其get()方法不接受任何參數(shù)但返回一個(gè)泛型類(lèi)型T的值。
這個(gè)接口被注解為@FunctionalInterface,表明它是一個(gè)函數(shù)式接口,可以用于Lambda表達(dá)式。

@FunctionalInterface
public interface Supplier<T> {
T get();
}
示例代碼:
import java.util.Random;
import java.util.function.Supplier;
public class Main {
public static void main(String[] args) {
// 創(chuàng)建一個(gè)Supplier接口的實(shí)例,通過(guò)Lambda表達(dá)式實(shí)現(xiàn)get()方法來(lái)生成隨機(jī)數(shù)
Supplier<Integer> randomSupplier = () -> {
Random random = new Random();
return random.nextInt(100); // 生成0到99的隨機(jī)數(shù)
};
int randomNumber = randomSupplier.get();
System.out.println("隨機(jī)數(shù):" + randomNumber);
}
}
Supplier接口的一個(gè)強(qiáng)大之處在于它支持惰性計(jì)算。這意味著生成值的計(jì)算只會(huì)在需要時(shí)才執(zhí)行。
例如以下示例,其中我們使用Supplier來(lái)延遲計(jì)算字符串的長(zhǎng)度:
String text = "Hello, World!";
Supplier<Integer> lengthSupplier = () -> text.length();
// 假設(shè)有一些其他耗時(shí)操作
int length = lengthSupplier.get();
System.out.println("字符串長(zhǎng)度:" + length);
在某些情況下,可以使用Supplier接口來(lái)處理異常情況。
例如,如果一個(gè)方法可能會(huì)拋出異常,可以使用Supplier來(lái)封裝這個(gè)方法,并在調(diào)用get()方法時(shí)捕獲異常:
import java.util.function.Supplier;
public class SupplierWithExceptionHandling {
public static void main(String[] args) {
// 創(chuàng)建一個(gè)Supplier實(shí)例,其中包含可能拋出異常的操作
Supplier<String> supplier = () -> {
try {
// 在這里執(zhí)行可能會(huì)拋出異常的操作
return "Hello, World!";
} catch (Exception e) {
// 處理異常情況
return "An error occurred: " + e.getMessage();
}
};
// 調(diào)用Supplier的get()方法,并處理可能的異常
try {
String result = supplier.get();
System.out.println(result);
} catch (Exception e) {
// 如果Supplier內(nèi)部的try-catch塊沒(méi)有處理異常,這里可以再次捕獲并處理
System.err.println("Error in Supplier: " + e.getMessage());
}
}
}
其中的lambda表達(dá)式包含了一個(gè)try-catch塊。當(dāng)調(diào)用supplier.get()時(shí),它會(huì)嘗試執(zhí)行可能會(huì)拋出異常的操作,并在catch塊中處理異常。
這樣,即使Supplier內(nèi)部的操作拋出了異常,程序仍然可以繼續(xù)運(yùn)行,并且可以根據(jù)需要處理異常情況。
Consumer
Consumer接口也是一個(gè)函數(shù)式接口,它表示一個(gè)接受單一輸入?yún)?shù)并且不返回任何結(jié)果的操作。 你可以把它想象成一個(gè)消費(fèi)者,你給它一個(gè)東西,它消費(fèi)掉這個(gè)東西,但不給你任何回報(bào)。
Consumer接口在Java 8中定義如下:
@FunctionalInterface
public interface Consumer<T> {
/**
* Performs this operation on the given argument.
*
* @param t the input argument
*/
void accept(T t);
}
Consumer接口中定義了一個(gè)accept方法,它接受一個(gè)泛型類(lèi)型T的參數(shù),并且沒(méi)有返回值(void)。此外,它還提供了一個(gè)默認(rèn)方法andThen,允許將多個(gè)Consumer串聯(lián)起來(lái),形成一個(gè)操作鏈。
使用示例,使用 Consumer 接口對(duì)集合中的元素進(jìn)行求和操作:
List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5);
// 使用 AtomicInteger 來(lái)保存結(jié)果
AtomicInteger sum = new AtomicInteger();
Consumer<Integer> addToSum = num -> sum.addAndGet(num);
numbers.forEach(addToSum);
System.out.println("Sum: " + sum); // 輸出 "Sum: 15"
條件執(zhí)行: 可以使用filter方法來(lái)創(chuàng)建一個(gè)僅在滿(mǎn)足特定條件時(shí)才執(zhí)行操作的Consumer。這對(duì)于過(guò)濾集合中的元素非常有用:
List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5);
Consumer<Integer> printEvenNumbers = n -> {
if (n % 2 == 0) {
System.out.println(n);
}
};
numbers.forEach(printEvenNumbers);
異常處理: 可以使用try-catch塊來(lái)處理Consumer中可能發(fā)生的異常。這可以確保即使發(fā)生錯(cuò)誤,程序也不會(huì)崩潰:
Consumer<String> printLength = s -> {
try {
System.out.println(s.length());
} catch (Exception e) {
System.err.println("Error processing string: " + e.getMessage());
}
};
printLength.accept("Hello, World!");
總結(jié)
- Consumer 接口為函數(shù)式編程提供了重要的支持。通過(guò)使用 Consumer 接口,我們可以輕松地定義并執(zhí)行一個(gè)接受一個(gè)參數(shù)并且不返回結(jié)果的操作。Consumer 接口特別適用于遍歷集合或執(zhí)行消費(fèi)型操作。
- Supplier接口提供了一種靈活而強(qiáng)大的機(jī)制來(lái)獲取或生成數(shù)據(jù),使用Supplier接口可以使代碼更加靈活和易于維護(hù),特別是在需要生成值或進(jìn)行惰性計(jì)算的情況里。
以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
相關(guān)文章
被kafka-client和springkafka版本坑到自閉及解決
這篇文章主要介紹了被kafka-client和springkafka版本坑到自閉及解決方案,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-03-03
IDEA運(yùn)行SpringBoot項(xiàng)目的圖文教程
本文主要介紹了IDEA運(yùn)行SpringBoot項(xiàng)目的圖文教程,文中通過(guò)圖文介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2024-05-05
MyBatis中的SQL映射文件配置結(jié)果映射的操作指南
MyBatis?是一款優(yōu)秀的?ORM?框架,它提供了多種配置方式來(lái)定義?SQL?語(yǔ)句以及結(jié)果映射規(guī)則,本文將介紹?MyBatis?中的?SQL?映射文件如何配置結(jié)果映射,包括常規(guī)類(lèi)型、集合類(lèi)型等多種情況,需要的朋友可以參考下2023-07-07
Java調(diào)用DOS實(shí)現(xiàn)定時(shí)關(guān)機(jī)的實(shí)例
Java調(diào)用DOS實(shí)現(xiàn)定時(shí)關(guān)機(jī)的實(shí)例,需要的朋友可以參考一下2013-04-04
spring?controller層引用service報(bào)空指針異常nullpointExceptio問(wèn)題
這篇文章主要介紹了spring?controller層引用service報(bào)空指針異常nullpointExceptio問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-02-02
springboot結(jié)合shiro實(shí)現(xiàn)身份認(rèn)證的實(shí)戰(zhàn)
本文主要介紹了springboot結(jié)合shiro實(shí)現(xiàn)身份認(rèn)證的實(shí)戰(zhàn),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2025-09-09
淺析SpringBoot統(tǒng)一返回結(jié)果的實(shí)現(xiàn)
前后端開(kāi)發(fā)過(guò)程中數(shù)據(jù)交互規(guī)范化是一件非常重要的事情,不僅可以減少前后端交互過(guò)程中出現(xiàn)的問(wèn)題,也讓代碼邏輯更加具有條理,下面小編就和大家講講SpringBoot如何統(tǒng)一返回結(jié)果的吧2023-07-07

