Java:Optional
创建Optional对象
1. 创建一个空的Optional对象
Optional<String> empty = Optional.empty();
使用 isPresent() 方法检查Optional对象中是否有值。
@Test
public void givenNonNull_whenCreatesNonNullable_thenCorrect() {
String name = "baeldung";
Optional<String> opt = Optional.of(name);
assertTrue(opt.isPresent());
}
2. 创建一个Optional对象
String name = "baeldung";
Optional<String> opt = Optional.of(name);
但是,传递给 of() 方法的参数不能为 null。 否则,我们将得到一个 NullPointerException。
@Test(expected = NullPointerException.class)
public void givenNull_whenThrowsErrorOnCreate_thenCorrect() {
String name = null;
Optional.of(name);
}
3. 创建一个可以接受null值的Optional对象
@Test
public void givenNonNull_whenCreatesNullable_thenCorrect() {
String name = "baeldung";
Optional<String> opt = Optional.ofNullable(name);
assertTrue(opt.isPresent());
}
使用null值创建:
@Test
public void givenNull_whenCreatesNullable_thenCorrect() {
String name = null;
Optional<String> opt = Optional.ofNullable(name);
assertFalse(opt.isPresent());
}
判断Optional是否为空
1. isPresent(),如果值不为 null,则返回 true。
@Test
public void givenOptional_whenIsPresentWorks_thenCorrect() {
Optional<String> opt = Optional.of("Baeldung");
assertTrue(opt.isPresent());
opt = Optional.ofNullable(null);
assertFalse(opt.isPresent());
}
2. isEmpty(),如果值为null,则返回true
@Test
public void givenAnEmptyOptional_thenIsEmptyBehavesAsExpected() {
Optional<String> opt = Optional.of("Baeldung");
assertFalse(opt.isEmpty());
opt = Optional.ofNullable(null);
assertTrue(opt.isEmpty());
}
Optional的使用
Optional<String> opt = Optional.of("baeldung");
if(opt != null) {
System.out.println(opt.length());
}
优化后
Optional<String> opt = Optional.of("baeldung");
opt.ifPresent(name -> System.out.println(name.length()));
使用orElse()
@Test
public void whenOrElseWorks_thenCorrect() {
String nullName = null;
String name = Optional.ofNullable(nullName).orElse("john");
assertEquals("john", name);
}
使用orElseGet()
@Test
public void whenOrElseGetWorks_thenCorrect() {
String nullName = null;
String name = Optional.ofNullable(nullName).orElseGet(() -> "john");
assertEquals("john", name);
}
它们的不同
@Test
public void whenOrElseGetAndOrElseOverlap_thenCorrect() {
String text = null;
String defaultText = Optional.ofNullable(text).orElseGet(this::getMyDefault);
assertEquals("Default Value", defaultText);
defaultText = Optional.ofNullable(text).orElse(getMyDefault());
assertEquals("Default Value", defaultText);
}
public String getMyDefault() {
System.out.println("Getting Default Value");
return "Default Value";
}
输出结果:
Getting default value... Getting default value...
在每种情况下都会调用 getMyDefault() 方法。 在值为null时,orElse() 和 orElseGet() 的工作方式完全相同。当在值不为null时,它们的运行结果就会不同:
@Test
public void whenOrElseGetAndOrElseDiffer_thenCorrect() {
String text = "Text present";
System.out.println("Using orElseGet:");
String defaultText
= Optional.ofNullable(text).orElseGet(this::getMyDefault);
assertEquals("Text present", defaultText);
System.out.println("Using orElse:");
defaultText = Optional.ofNullable(text).orElse(getMyDefault());
assertEquals("Text present", defaultText);
}
输出结果:
Using orElseGet: Using orElse: Getting default value...
所以在使用像orMyDefault()的方法是不管值是否为空方法都会被运行。
方法会被运行但是返回的还是optional中的值。
使用orElseThrow()
@Test(expected = IllegalArgumentException.class)
public void whenOrElseThrowWorks_thenCorrect() {
String nullName = null;
String name = Optional.ofNullable(nullName).orElseThrow(IllegalArgumentException::new);
}
Java10的更新中可以不传输parameter
@Test(expected = NoSuchElementException.class)
public void whenNoArgOrElseThrowWorks_thenCorrect() {
String nullName = null;
String name = Optional.ofNullable(nullName).orElseThrow();
}
使用get()返回值
@Test
public void givenOptional_whenGetsValue_thenCorrect() {
Optional<String> opt = Optional.of("baeldung");
String name = opt.get();
assertEquals("baeldung", name);
}
get() 仅当包装对象不为 null 时才能返回值; 否则,它会抛出 no such element 异常
@Test(expected = NoSuchElementException.class)
public void givenOptionalWithNull_whenGetThrowsException_thenCorrect() {
Optional<String> opt = Optional.ofNullable(null);
String name = opt.get();
}
使用filter()
@Test
public void whenOptionalFilterWorks_thenCorrect() {
Integer year = 2016;
Optional<Integer> yearOptional = Optional.of(year);
boolean is2016 = yearOptional.filter(y -> y == 2016).isPresent();
assertTrue(is2016);
boolean is2017 = yearOptional.filter(y -> y == 2017).isPresent();
assertFalse(is2017);
}
例子
public boolean priceIsInRange1(Modem modem) {
boolean isInRange = false;
if (modem != null && modem.getPrice() != null
&& (modem.getPrice() >= 10
&& modem.getPrice() <= 15)) {
isInRange = true;
}
return isInRange;
}
优化后
public boolean priceIsInRange2(Modem modem2) {
return Optional.ofNullable(modem2)
.map(Modem::getPrice)
.filter(p -> p >= 10)
.filter(p -> p <= 15)
.isPresent();
}
.map() 的使用
@Test
public void givenOptional_whenMapWorks_thenCorrect() {
List<String> companyNames = Arrays.asList(
"paypal", "oracle", "", "microsoft", "", "apple");
Optional<List<String>> listOptional = Optional.of(companyNames);
int size = listOptional
.map(List::size)
.orElse(0);
assertEquals(6, size);
}
例子2.
@Test
public void givenOptional_whenMapWorks_thenCorrect2() {
String name = "baeldung";
Optional<String> nameOptional = Optional.of(name);
int len = nameOptional
.map(String::length)
.orElse(0);
assertEquals(8, len);
}
例子3.
@Test
public void givenOptional_whenMapWorksWithFilter_thenCorrect() {
String password = " password ";
Optional<String> passOpt = Optional.of(password);
boolean correctPassword = passOpt.filter(
pass -> pass.equals("password")).isPresent();
assertFalse(correctPassword);
correctPassword = passOpt
.map(String::trim)
.filter(pass -> pass.equals("password"))
.isPresent();
assertTrue(correctPassword);
}
使用 .flatMap()
public class Person {
private String name;
private int age;
private String password;
public Optional<String> getName() {
return Optional.ofNullable(name);
}
public Optional<Integer> getAge() {
return Optional.ofNullable(age);
}
public Optional<String> getPassword() {
return Optional.ofNullable(password);
}
// normal constructors and setters
}
@Test
public void givenOptional_whenFlatMapWorks_thenCorrect2() {
Person person = new Person("john", 26);
Optional<Person> personOptional = Optional.of(person);
Optional<Optional<String>> nameOptionalWrapper
= personOptional.map(Person::getName);
Optional<String> nameOptional
= nameOptionalWrapper.orElseThrow(IllegalArgumentException::new);
String name1 = nameOptional.orElse("");
assertEquals("john", name1);
String name = personOptional
.flatMap(Person::getName)
.orElse("");
assertEquals("john", name);
}

浙公网安备 33010602011771号