Java8 提供的Optional<T>讓java程序員不用再老檢查null彻磁,就是在任何對(duì)象前面包一層Optional,然后直接用這個(gè)Optional對(duì)象就行了辆毡。判空在optional內(nèi)部進(jìn)行珊楼。
常見(jiàn)寫(xiě)法:
User findUserById(String userId) { ... };
User user = findUserById("667290");
if(user!=null){
System.out.println("User's Name = " + user.getName());
}
不是所有的時(shí)候都會(huì)記得寫(xiě)if(user!=null),引入Optional之后的寫(xiě)法:
Optional<User> findUserById(String userId) { ... };
Optional<User> optionalUser = findUserById("667290");
optionalUser.ifPresent(user -> {
System.out.println("User's name = " + user.getName());
})
ifPresent()這個(gè)函數(shù)在optionalUser不為空的時(shí)候會(huì)被調(diào)用夫偶,否則什么都不做。
創(chuàng)造Optional 對(duì)象
1 創(chuàng)造空對(duì)象
Optional<User> user = Optional.empty(); //而不是 User user = null;
2.創(chuàng)造非空對(duì)象
User user = new User("667290", "Rajeev Kumar Singh");
Optional<User> userOptional = Optional.of(user);
3.用一個(gè)可能為空的對(duì)象創(chuàng)造一個(gè)Optional對(duì)象
Optional<User> userOptional = Optional.ofNullable(user); // 如果user為空嘉抓,返回 Optional.empty()灵巧,否則返回一個(gè) Optional<User> 對(duì)象
判斷為空 optional.isPresent()
if(optionalUser.isPresent()) {
// value is present inside Optional
System.out.println("Value found - " + optionalUser.get());
} else {
// value is absent
System.out.println("optionalUser is empty");
}
- 判斷為空 ifPresent()
optionalUser.ifPresent(value -> {
System.out.println("Value found - " + value);
});
ifPresent 可以傳入一個(gè)lambda表達(dá)式拔恰,如果為空則不執(zhí)行。
從Optional對(duì)象里獲取對(duì)象
optionalUser不為空硫惕,則get獲取到user杨赤,否則報(bào)錯(cuò) [NoSuchElementException]敞斋,所以在這里還是需要先isPresent或者ifPresent判斷為空截汪。
User user = optionalUser.get();
返回不為空的默認(rèn)值orElse()
optional為空植捎,則直接返回一個(gè)默認(rèn)對(duì)象
比如衙解,我們不想ruturn一個(gè)null,而是想return一個(gè)id為0的用戶:
optionalUser=...
User finalUser = optionalUser.orElse(new User("0", "Unknown User"));
//老的寫(xiě)法
//user = ...
//User finalUser = (user != null) ? user : new User("0", "Unknown User");
返回不為空的默認(rèn)值orElseGet()
optional為空焰枢,則直接返回一個(gè)函數(shù)執(zhí)行結(jié)果蚓峦。
User finalUser = optionalUser.orElseGet(() -> {
return new User("0", "Unknown User");
});
拋出異常 orElseThrow()
Optional 為空,拋出異常济锄。
@GetMapping("/users/{userId}")
public User getUser(@PathVariable("userId") String userId) {
return userRepository.findByUserId(userId).orElseThrow(
() -> new ResourceNotFoundException("User not found with userId " + userId);
);
}
增加if邏輯 filter()
比如說(shuō)暑椰,只對(duì)男性進(jìn)行處理。
userOptional不為空荐绝,并且滿足“MALE”一汽,會(huì)執(zhí)行ifPresent里的函數(shù),否則返回一個(gè)empty Optional
userOptional.filter(user -> user.getGender().equalsIgnoreCase("MALE"))
.ifPresent(() -> {
// 只在userOptional不為空并且為男性的時(shí)候執(zhí)行
})
//老的寫(xiě)法:
//if(user != null && user.getGender().equalsIgnoreCase("MALE")) {
// // Todo
//}
數(shù)據(jù)處理 map()
比如獲取用戶的地址為“india”的用戶的地址低滩。map()會(huì)返回用戶地址召夹,如果用戶為空或者地址為空,則返回 optional empty
userOptional.flatmap(User::getAddress)
.filter(address -> address.getCountry().equalsIgnoreCase("india"))
.ifPresent(() -> {
System.out.println("User belongs to India"); // 用戶不為空恕沫,用戶地址也不為空才執(zhí)行
});
// 老的寫(xiě)法:
//if(user != null) {
// Address address = user.getAddress();
// if(address != null && address.getCountry().equalsIgnoreCase("India")) {
// System.out.println("User belongs to India");
// }
//}
常見(jiàn)的數(shù)據(jù)轉(zhuǎn)換:
public String getCity(User user) throws Exception{
if(user!=null){
if(user.getAddress()!=null){
Address address = user.getAddress();
if(address.getCity()!=null){
return address.getCity();
}
}
}
throw new Excpetion("取值錯(cuò)誤");
}
//新寫(xiě)法:
public String getCity(User user) throws Exception{
return Optional.ofNullable(user)
.map(u-> u.getAddress())
.map(a->a.getCity())
.orElseThrow(()->new Exception("取指錯(cuò)誤"));
}