| 知乎专栏 |
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());