| 知乎專欄 | 多維度架構 | | | 微信號 netkiller-ebook | | | QQ群:128659835 請註明“讀者” |
Optional.of("javastack").orElseThrow(); // javastack
// 1
of方法通過工廠方法創建Optional類。需要注意的是,創建對象時傳入的參數不能為null。如果傳入參數為null,則拋出NullPointerException 。
Optional<String> name = Optional.of("netkiller");
if (name.isPresent()) {
// 在Optional實例內調用get()返回已存在的值
System.out.println(name.get());// 輸出 netkiller
}
傳入參數為null,拋出NullPointerException.
Optional<String> someNull = Optional.of(null);
Optional<String> name = Optional.ofNullable("netkiller");
if (name.isPresent()) {
// 在Optional實例內調用get()返回已存在的值
System.out.println(name.get());// 輸出 netkiller
}
Optional<String> empty = Optional.ofNullable(null);
if (empty.isPresent()) {
System.out.println(empty.get());
}
//isPresent方法用來檢查Optional實例中是否包含值
if (name.isPresent()) {
System.out.println(name.get());
}
如果Optional實例有值,調用ifPresent()可以接受介面段或lambda表達式。類似下面的代碼:
Optional<String> name = Optional.ofNullable("netkiller");
name.ifPresent((value) -> {
System.out.println("hello " + value);
});
name.ifPresent((value) -> {
System.out.println(value.length());
});
如果Optional有值則將其返回,否則拋出NoSuchElementException。
Optional<String> name = Optional.ofNullable("netkiller");
System.out.println(name.get());
Optional<String> empty = Optional.ofNullable(null);
try {
System.out.println(empty.get());
} catch (NoSuchElementException e) {
System.out.println(e.getMessage());
}
輸出內容
netkiller No value present
如果Optional實例有值則將其返回,否則返回orElse方法傳入的參數。示例如下:
package cn.netkiller.test;
import java.util.Optional;
public class OptionalTest {
public OptionalTest() {
// TODO Auto-generated constructor stub
}
public static void main(String[] args) {
Optional<String> name = Optional.ofNullable("netkiller");
Optional<String> empty = Optional.ofNullable(null);
System.out.println(name.orElse("There is some value!"));
System.out.println(empty.orElse("There is no value present!"));
}
}
輸出
netkiller There is no value present!
指定預設值
User user = new User();
user.setId(1);
user.setUsername("Neo");
Optional<User> user = Optional.ofNullable(user).orElse(new User(0, "Unknown"));
System.out.println("Username is: " + user.getUsername());
orElseGet方法可以接受Supplier介面的實現用來生成預設值。示例如下:
package cn.netkiller.test;
import java.util.Optional;
public class OptionalTest {
public OptionalTest() {
// TODO Auto-generated constructor stub
}
public static void main(String[] args) {
Optional<String> name = Optional.ofNullable("netkiller");
Optional<String> empty = Optional.ofNullable(null);
System.out.println(name.orElseGet(() -> "There is some value!"));
System.out.println(empty.orElseGet(() -> "There is no value present!"));
}
}
Optional<User> user = Optional.ofNullable(user).orElseGet(() -> new User(0, "Unknown"));
Optional<User> user = Optional
.ofNullable(user)
.orElseThrow(() -> new EntityNotFoundException("id=" + id + " 的用戶沒有找到"));
使用場景舉例
@RequestMapping("/user/{id}")
public User getUser(@PathVariable Integer id) {
Optional<User> user = userService.getUserById(id);
return user.orElseThrow(() -> new EntityNotFoundException("id=" + id + " 的用戶不存在"));
}
@ExceptionHandler(EntityNotFoundException.class)
public ResponseEntity<String> handleException(EntityNotFoundException ex) {
return new ResponseEntity<>(ex.getMessage(), HttpStatus.NOT_FOUND);
}
package cn.netkiller.test;
import java.util.Optional;
public class OptionalTest {
public OptionalTest() {
// TODO Auto-generated constructor stub
}
public static class ValueAbsentException extends Throwable {
private static final long serialVersionUID = -1758502952187236809L;
public ValueAbsentException() {
super();
}
public ValueAbsentException(String msg) {
super(msg);
}
@Override
public String getMessage() {
return "No value present in the Optional instance";
}
}
public static void main(String[] args) {
Optional<String> empty = Optional.ofNullable(null);
try {
// orElseThrow會拋出lambda表達式或方法生成的異常
empty.orElseThrow(ValueAbsentException::new);
} catch (Throwable ex) {
// 輸出 No value present in the Optional instance
System.out.println(ex.getMessage());
}
}
}
map方法用來對Optional實例的值執行一系列操作。通過一組實現了Function介面的lambda表達式傳入操作。map方法示例如下:
Optional<String> name = Optional.ofNullable("netkiller");
Optional<String> upperName = name.map((value) -> value.toUpperCase());
System.out.println(upperName.orElse("No value found"));
Optional<String> username = Optional.ofNullable("netKiller-Neo")
.map((value) -> value.toLowerCase())
.map((value) -> value.replace("n", "N"))
.map(value -> value.replace('-', '_'));
System.out.println("Username is: " + username.orElse("Unknown"));
與 map() 區別在於flatMap中的mapper返回值必須是Optional
Optional<String> username = Optional.ofNullable("netKiller-Neo").flatMap((value) -> Optional.of(value.toUpperCase()));
System.out.println("Username is: " + username.orElse("No value found"));
package cn.netkiller.test;
import java.util.Arrays;
import java.util.List;
import java.util.Optional;
public class OptionalTest {
public OptionalTest() {
// TODO Auto-generated constructor stub
}
public static void main(String[] args) {
for (String item : List.of("Neo", "Jerry", "Netkiller")) {
Optional<String> username = Optional.of(item).filter((value) -> value.length() > 6);
System.out.println("name is: " + username.orElse("The name is less than 6 characters"));
}
}
}
使用多個 filter 組合過濾數據
List.of("Neo", "Jerry", "Netkiller", "Tom", "Anni", "Lisa", "Leo").forEach(item -> {
Optional.of(item).filter((value) -> value.length() > 2).filter((value) -> value.contains("o")).ifPresent((n) -> {
System.out.println(n);
});
});
String string = (String) Optional.ofNullable(null).or(() -> Optional.of("netkiller")).get();
System.out.println(string);
Optional<Map<String, Object>> name = Optional.of(new HashMap<String, Object>() {
{
put("id", 1);
put("name", "Neo");
put("age", 30);
}
});
System.out.println(name.toString());
name.map((m) -> m.put("count", 1));
System.out.println(name.get());
name.map((m) -> m.put("nickname", "netkiller"));
name.map((m) -> m.remove("id"));
System.out.println(name.get());
Optional<Map<String, Object>> tmp = name.filter((m) -> ((Integer) m.get("age")) == 30);
System.out.println("filter: " + tmp.get());