一髓抑、背景
有時(shí)候在處理業(yè)務(wù)邏輯時(shí),需要判斷方法返回的值是否為 null 优幸。如启昧,根據(jù)用戶ID查找用戶,Service層代碼如下:
public User findUserById(int id) {
return userMapper.findUserById(id);
}
Controller層代碼如下:
User user = userService.findUserById(id);
if(user==null)
//throw exception
else
//ok
新版本的Java,比如Java 8引入了一個(gè)新的Optional類劈伴。Optional類的Javadoc描述如下:
這是一個(gè)可以為null的容器對(duì)象密末。如果值存在則isPresent()方法會(huì)返回true握爷,調(diào)用get()方法會(huì)返回該對(duì)象。
二严里、用法
1. of
為非null的值創(chuàng)建一個(gè)Optional新啼。of方法通過(guò)工廠方法創(chuàng)建Optional類。需要注意的是刹碾,創(chuàng)建對(duì)象時(shí)傳入的參數(shù)不能為null燥撞。如果傳入?yún)?shù)為null,則拋出NullPointerException 迷帜。
//調(diào)用工廠方法創(chuàng)建Optional實(shí)例
Optional<String> name = Optional.of("Sanaulla");
//傳入?yún)?shù)為null物舒,拋出NullPointerException.
Optional<String> someNull = Optional.of(null);
2. ofNullable
為指定的值創(chuàng)建一個(gè)Optional,如果指定的值為null戏锹,則返回一個(gè)空的Optional冠胯。
ofNullable與of方法相似,唯一的區(qū)別是可以接受參數(shù)為null的情況锦针。示例如下:
//下面創(chuàng)建了一個(gè)不包含任何值的Optional實(shí)例
//例如荠察,值為'null'
Optional empty = Optional.ofNullable(null);
3. isPresent
如果值存在返回true,否則返回false奈搜。
//isPresent方法用來(lái)檢查Optional實(shí)例中是否包含值
if (name.isPresent()) {
//在Optional實(shí)例內(nèi)調(diào)用get()返回已存在的值
System.out.println(name.get());//輸出Sanaulla
}
4. map
如果有值悉盆,則對(duì)其執(zhí)行調(diào)用mapping函數(shù)得到返回值。如果返回值不為null馋吗,則創(chuàng)建包含mapping返回值的Optional作為map方法返回值焕盟,否則返回空Optional。
//map方法執(zhí)行傳入的lambda表達(dá)式參數(shù)對(duì)Optional實(shí)例的值進(jìn)行修改宏粤。
//為lambda表達(dá)式的返回值創(chuàng)建新的Optional實(shí)例作為map方法的返回值京髓。
Optional<String> upperName = name.map((value) -> value.toUpperCase());
System.out.println(upperName.orElse("No value found"));
完整實(shí)例
public class OptionalDemo {
public static void main(String[] args) {
//創(chuàng)建Optional實(shí)例,也可以通過(guò)方法返回值得到商架。
Optional<String> name = Optional.of("Sanaulla");
//創(chuàng)建沒(méi)有值的Optional實(shí)例堰怨,例如值為'null'
Optional empty = Optional.ofNullable(null);
//isPresent方法用來(lái)檢查Optional實(shí)例是否有值。
if (name.isPresent()) {
//調(diào)用get()返回Optional值蛇摸。
System.out.println(name.get());
}
try {
//在Optional實(shí)例上調(diào)用get()拋出NoSuchElementException备图。
System.out.println(empty.get());
} catch (NoSuchElementException ex) {
System.out.println(ex.getMessage());
}
//ifPresent方法接受lambda表達(dá)式參數(shù)。
//如果Optional值不為空赶袄,lambda表達(dá)式會(huì)處理并在其上執(zhí)行操作揽涮。
name.ifPresent((value) -> {
System.out.println("The length of the value is: " + value.length());
});
//如果有值orElse方法會(huì)返回Optional實(shí)例,否則返回傳入的錯(cuò)誤信息饿肺。
System.out.println(empty.orElse("There is no value present!"));
System.out.println(name.orElse("There is some value!"));
//orElseGet與orElse類似蒋困,區(qū)別在于傳入的默認(rèn)值。
//orElseGet接受lambda表達(dá)式生成默認(rèn)值敬辣。
System.out.println(empty.orElseGet(() -> "Default Value"));
System.out.println(name.orElseGet(() -> "Default Value"));
try {
//orElseThrow與orElse方法類似雪标,區(qū)別在于返回值零院。
//orElseThrow拋出由傳入的lambda表達(dá)式/方法生成異常。
empty.orElseThrow(ValueAbsentException::new);
} catch (Throwable ex) {
System.out.println(ex.getMessage());
}
//map方法通過(guò)傳入的lambda表達(dá)式修改Optonal實(shí)例默認(rèn)值村刨。
//lambda表達(dá)式返回值會(huì)包裝為Optional實(shí)例告抄。
Optional<String> upperName = name.map((value) -> value.toUpperCase());
System.out.println(upperName.orElse("No value found"));
//flatMap與map(Funtion)非常相似,區(qū)別在于lambda表達(dá)式的返回值嵌牺。
//map方法的lambda表達(dá)式返回值可以是任何類型打洼,但是返回值會(huì)包裝成Optional實(shí)例。
//但是flatMap方法的lambda返回值總是Optional類型逆粹。
upperName = name.flatMap((value) -> Optional.of(value.toUpperCase()));
System.out.println(upperName.orElse("No value found"));
//filter方法檢查Optiona值是否滿足給定條件募疮。
//如果滿足返回Optional實(shí)例值,否則返回空Optional僻弹。
Optional<String> longName = name.filter((value) -> value.length() > 6);
System.out.println(longName.orElse("The name is less than 6 characters"));
//另一個(gè)示例阿浓,Optional值不滿足給定條件。
Optional<String> anotherName = Optional.of("Sana");
Optional<String> shortName = anotherName.filter((value) -> value.length() > 6);
System.out.println(shortName.orElse("The name is less than 6 characters"));
}
}
輸出:
Sanaulla
No value present
The length of the value is: 8
There is no value present!
Sanaulla
Default Value
Sanaulla
No value present in the Optional instance
SANAULLA
SANAULLA
Sanaulla
The name is less than 6 characters
原文鏈接: javacodegeeks 翻譯: ImportNew.com - 高俊陽(yáng)譯文鏈接: http://www.importnew.com/6675.html
三奢方、改進(jìn)
public Optional<User> findUserById(int id) {
return Optional.ofNullable(userMapper.findUserById(id));
}
public ResponseEntity<?> findUserById( @PathVariable("id") int id){
log.info("======enter UserController method======");
return userService
.findUserById(id)
.map(ResponseEntity::ok)
.orElseThrow(() -> new ResourceNotFoundException()
.setResourceName(ResourceNameConstant.USER)
.setId(id));
}