Java 中 Function 與 apply 的實(shí)際應(yīng)用場景分析(含優(yōu)化前后案例)
在日常開發(fā)中,我們會遇到一些代碼重復(fù)度高、邏輯結(jié)構(gòu)雷同的場景,比如:
- 針對多個(gè)字段做相似的判空判斷
- 對多個(gè)字段的數(shù)值格式進(jìn)行統(tǒng)一處理
- 動態(tài)構(gòu)造 VO 或 DTO 列表
以前這些邏輯通常依賴大量 if-else,導(dǎo)致代碼冗長、可讀性差。隨著 Java 8 Lambda 的流行,我們可以借助 Function 函數(shù)式接口 讓代碼更簡潔、更易維護(hù)。
本文通過一個(gè)實(shí)際場景,講解:
- Function 是什么
- apply 方法的作用
- 在實(shí)際業(yè)務(wù)里如何利用 Function 簡化重復(fù)邏輯
- 更多 Function 的高級用法
?? 一、Function 是什么?
Java 8 提供了大量函數(shù)式接口(位于 java.util.function 包里),其中 Function<T, R> 是最常用的一個(gè):

簡單理解:
Function 表示一個(gè)“輸入一個(gè)參數(shù)(T),輸出一個(gè)結(jié)果(R)”的函數(shù)。
例如:
- 輸入是
String,輸出是Integer - 輸入是一個(gè)實(shí)體對象,輸出是某個(gè)字段的值
- 輸入是一個(gè)可能為 null 的字段,輸出是安全值
?? 二、apply 做什么?
apply() 是 Function 的核心方法,用來執(zhí)行函數(shù)邏輯,你可以把 apply() 理解成“執(zhí)行這個(gè)函數(shù)”。比如如下方法,我們需要獲取每個(gè)字符串的字符串長度:
Function<String, Integer> lengthFunc = str -> str.length();
int len = lengthFunc.apply("hello"); // 返回 5
?? 三、業(yè)務(wù)場景:字段多、判空多、邏輯重復(fù)
??1、傳統(tǒng)做法
假設(shè)我們有一個(gè)實(shí)體(例如某企業(yè)的年度指標(biāo)數(shù)據(jù)):
class IndicatorEntity {
private String amountA;
private String amountB;
private String amountC;
// ...getter/setter
}
我們需要根據(jù)它生成一個(gè) VO 列表,輸出時(shí)存在各種問題,比如
- 字段可能為 null
- 字段可能為空字符串
- 需要統(tǒng)一格式化為兩位小數(shù)
- 需要填充默認(rèn)值 “0”……
傳統(tǒng)寫法會有大量的 if-else 判斷,大量重復(fù)(下述代碼中 format() 表示規(guī)范字段的值,如實(shí)現(xiàn)判空、保留兩位小數(shù)等邏輯):
List<ItemVO> list = new ArrayList<>();
if (StringUtils.isNotBlank(entity.getAmountA())) {
list.add(new ItemVO("指標(biāo)A", format(entity.getAmountA()), "噸"));
} else {
list.add(new ItemVO("指標(biāo)A", "0", "噸"));
}
if (StringUtils.isNotBlank(entity.getAmountB())) {
list.add(new ItemVO("指標(biāo)B", format(entity.getAmountB()), "噸"));
} else {
list.add(new ItemVO("指標(biāo)B", "0", "噸"));
}
// ...重復(fù)更多??2、使用 Function 優(yōu)化:統(tǒng)一 null 處理與格式化
我們使用一個(gè) Function<String, String>,用于將字段安全地轉(zhuǎn)換成非空:
Function<String, String> safeFormat = val -> val == null ? "" : val;
之后構(gòu)造字段數(shù)組如下:
Object[][] fields = {
{"指標(biāo)A", safeFormat.apply(entity.getAmountA()), "噸"},
{"指標(biāo)B", safeFormat.apply(entity.getAmountB()), "噸"},
{"指標(biāo)C", safeFormat.apply(entity.getAmountC()), "噸"},
// 其他指標(biāo)依次添加
};
之后對其統(tǒng)一格式化處理:
List<ItemVO> result = new ArrayList<>();
for (Object[] field : fields) {
String name = (String) field[0];
String rawValue = (String) field[1];
String unit = (String) field[2];
String formattedValue = "0";
if (StringUtils.isNotBlank(rawValue)) {
try {
// 統(tǒng)一格式化,例如 NumberUtil.formatStr(),或其他你需要對字符串進(jìn)行的操作
formattedValue = format(rawValue);
} catch (Exception ignored) {
// 你需要進(jìn)行的異常操作
}
}
result.add(new ItemVO(name, formattedValue, unit));
}經(jīng)過優(yōu)化后:
- 重復(fù)邏輯消失
- 判空與格式化集中處理
- 字段配置化,易維護(hù)
- 添加新字段只需改一個(gè)數(shù)組,便于之后添加字段到處添加 if-else,修改方便。
?? 四、Function 的實(shí)際適用場景總結(jié)
① null 安全處理(最常見)
② 字段提取器(Getter 復(fù)用)——比如多字段統(tǒng)一處理,適用于:動態(tài)抽取實(shí)體字段值、在工具類中避免大量重復(fù) getter 調(diào)用:
<T, R> R getValue(T entity, Function<T, R> getter) {
return getter.apply(entity);
}
String value = getValue(entity, IndicatorEntity::getAmountA);③ 通用格式化處理——例如統(tǒng)一格式化數(shù)字、日期:
Function<String, String> formatAmount = s -> {
if (StringUtils.isBlank(s)) return "0";
return NumberUtil.formatStr(s, 2);
};
④ 配置化字段處理
如本文案例,將字段名稱、原始值、單位放在數(shù)組或列表中,之后統(tǒng)一判空、格式化、填充默認(rèn)值、構(gòu)造VO。
?? 五、進(jìn)一步延申:組合函數(shù) compose 與 andThen
compose:先執(zhí)行參數(shù)里的 Function,再執(zhí)行當(dāng)前 Function
Function<String, Integer> length = s -> s.length();
Function<String, String> trim = s -> s.trim();
int len = length.compose(trim).apply(" hi "); // 2andThen:先執(zhí)行當(dāng)前 Function,再執(zhí)行參數(shù)里的 Function
int len = trim.andThen(length).apply(" hi "); // 2
適用于多步驟處理,例如:
- 先判空 → 再格式化
- 先 trim → 再校驗(yàn)
到此這篇關(guān)于Java 中 Function 與 apply 的實(shí)際應(yīng)用場景分析(含優(yōu)化前后案例)的文章就介紹到這了,更多相關(guān)java function 與 apply用法內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
學(xué)習(xí)Java之二叉樹的編碼實(shí)現(xiàn)過程詳解
本文將通過代碼來進(jìn)行二叉樹的編碼實(shí)現(xiàn),文中的代碼示例介紹的非常詳細(xì),對我們學(xué)習(xí)Java二叉樹有一定的幫助,感興趣的同學(xué)跟著小編一起來看看吧2023-08-08
快速解決VS Code報(bào)錯(cuò):Java 11 or more recent is required to run. Ple
這篇文章主要介紹了快速解決VS Code報(bào)錯(cuò):Java 11 or more recent is required to run. Please download and install a recent JDK的相關(guān)資料,需要的朋友可以參考下2020-09-09
Mybatis 查詢語句條件為枚舉類型時(shí)報(bào)錯(cuò)的解決
這篇文章主要介紹了Mybatis 查詢語句條件為枚舉類型時(shí)報(bào)錯(cuò)的解決方案,具有很好的參考價(jià)值,希望對大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-01-01
Struts2學(xué)習(xí)手冊之文件上傳基礎(chǔ)教程
Struts2提供的文件上傳下載機(jī)制十分簡便,使得我們寫很少的代碼,下面這篇文章主要給大家介紹了關(guān)于Struts2學(xué)習(xí)手冊之文件上傳的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),需要的朋友可以參考下2018-05-05
Mybatis從3.4.0版本到3.5.7版本的迭代方法實(shí)現(xiàn)
本文主要介紹了Mybatis從3.4.0版本到3.5.7版本的迭代方法實(shí)現(xiàn),包括主要的功能增強(qiáng)、不兼容的更改和修復(fù)的錯(cuò)誤,具有一定的參考價(jià)值,感興趣的可以了解一下2025-03-03
MyBatis關(guān)聯(lián)查詢的實(shí)現(xiàn)
MyBatis可以通過定義多個(gè)表的關(guān)聯(lián)關(guān)系,實(shí)現(xiàn)多表查詢,本文主要介紹了MyBatis關(guān)聯(lián)查詢的實(shí)現(xiàn),具有一定的參考價(jià)值,感興趣的可以了解一下2023-11-11
基于SpringBoot2.0默認(rèn)使用Redis連接池的配置操作
這篇文章主要介紹了基于SpringBoot2.0默認(rèn)使用Redis連接池的配置操作,具有很好的參考價(jià)值,希望對大家有所幫助。一起跟隨小編過來看看吧2020-12-12

