知乎專欄 | 多維度架構 | | | 微信號 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());