知乎专栏 |
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()); }
ifEmpty() 与 ifPresent() 刚好相反
如果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());
package cn.netkiller.utils; import lombok.Data; import lombok.extern.slf4j.Slf4j; import java.io.Serial; import java.io.Serializable; import java.util.Optional; @Data @Slf4j public class ResponseJson implements Serializable { @Serial private static final long serialVersionUID = 1L; private final boolean status; // 状态代码 private final Code code; // 业务响应码 private final Object data; // 返回业务参数 private String reason = ""; // 返回信息描述 public ResponseJson(boolean status, Code code, String reason, Object data) { this.status = status; this.code = code; this.reason = reason; this.data = data; } public ResponseJson(Object data) { Optional<Object> optional = Optional.ofNullable(data); // log.info(String.valueOf(optional.isEmpty())); // log.info(String.valueOf(optional.isPresent())); // log.info(String.valueOf(optional.get())); if (optional.isEmpty()) { this.status = false; this.code = Code.FAIL; this.reason = "失败"; this.data = null; } else { this.status = true; this.code = Code.SUCCESS; this.reason = "成功"; this.data = data; } } public enum Code { SUCCESS, // 业务处理成功 COMPLIANCE, NONCOMPLIANT, ILLEGAL, FAIL // 业务处理失败 } }
当 dish 为空,将返回 new Dish()
Optional<Dish> dish1 = Optional.of(dish).orElse(new Dish());