本文參考自: 原文地址
JAVA之工具類Optional
一. 概述
package java.util;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.function.Predicate;
import java.util.function.Supplier;
public final class Optional<T> {
private static final Optional<?> EMPTY = new Optional<>();
private final T value;
private Optional() {
this.value = null;
}
public static<T> Optional<T> empty() {
@SuppressWarnings("unchecked")
Optional<T> t = (Optional<T>) EMPTY;
return t;
}
private Optional(T value) {
this.value = Objects.requireNonNull(value);
}
public static <T> Optional<T> of(T value) {
return new Optional<>(value);
}
public static <T> Optional<T> ofNullable(T value) {
return value == null ? empty() : of(value);
}
public T get() {
if (value == null) {
throw new NoSuchElementException("No value present");
}
return value;
}
public boolean isPresent() {
return value != null;
}
public void ifPresent(Consumer<? super T> consumer) {
if (value != null)
consumer.accept(value);
}
public Optional<T> filter(Predicate<? super T> predicate) {
Objects.requireNonNull(predicate);
if (!isPresent())
return this;
else
return predicate.test(value) ? this : empty();
}
public<U> Optional<U> map(Function<? super T, ? extends U> mapper) {
Objects.requireNonNull(mapper);
if (!isPresent())
return empty();
else {
return Optional.ofNullable(mapper.apply(value));
}
}
public<U> Optional<U> flatMap(Function<? super T, Optional<U>> mapper) {
Objects.requireNonNull(mapper);
if (!isPresent())
return empty();
else {
return Objects.requireNonNull(mapper.apply(value));
}
}
public T orElse(T other) {
return value != null ? value : other;
}
public T orElseGet(Supplier<? extends T> other) {
return value != null ? value : other.get();
}
public <X extends Throwable> T orElseThrow(Supplier<? extends X> exceptionSupplier) throws X {
if (value != null) {
return value;
} else {
throw exceptionSupplier.get();
}
}
@Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (!(obj instanceof Optional)) {
return false;
}
Optional<?> other = (Optional<?>) obj;
return Objects.equals(value, other.value);
}
@Override
public int hashCode() {
return Objects.hashCode(value);
}
@Override
public String toString() {
return value != null
? String.format("Optional[%s]", value)
: "Optional.empty";
}
}
這麼多方法是不是驚呆了.首先先從
構造方法講起.
1. empty方法(私有)
2. of方法
3. ofNullable方法
4. isPresent方法
5. get方法
6. ifPresent方法
7. orElse方法
8. orElseGet方法
9. orElseThrow方法
10. filter方法
11. map方法
12. flatMap方法
如同第11方法,但是其返回值必須是一個Optianal類型的對象.
二. 示例
package com.yczuoxin.demo.optional;
public class User {
private String name;
private Integer age;
public User() {
}
public User(String name, Integer age) {
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
@Override
public String toString() {
return "User{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
}
1. 傳入一個對象,如果是空我們不做任何操作,如果不是空,就講對象打印出來.
package com.yczuoxin.demo.optional;
import java.util.Optional;
public class OptionalTest {
public static void main(String[] args) {
Optional<User> user = Optional.ofNullable(new User("張三",18));
Optional<User> empty = Optional.ofNullable(null);
user.ifPresent(existUser -> System.out.println(existUser));
}
}
測試成功,只打印出了非空的結果.注意,此處如果用of代替ofNullable的話會直接拋出異常.
2. 傳入一個字符串,如果是空,則返回empty string, 如果不是空則返回其值.
package com.yczuoxin.demo.optional;
import java.util.Optional;
public class OptionalTest {
public static void main(String[] args) {
Optional<String> str = Optional.ofNullable("string");
Optional<String> empty = Optional.ofNullable(null);
System.out.println(str.orElse("new string"));
System.out.println(empty.orElse("empty string"));
}
}
也可以使用另一個方法
package com.yczuoxin.demo.optional;
import java.util.Optional;
public class OptionalTest {
public static void main(String[] args) {
Optional<String> str = Optional.ofNullable("string");
Optional<String> empty = Optional.ofNullable(null);
System.out.println(str.orElseGet(() -> new String("is empty")));
System.out.println(empty.orElseGet(() -> new String("is empty")));
}
}
測試成功.
3. 傳入一個用戶,如果用戶存在,則獲取用戶的用戶名,並將其用戶名的字母全部大寫輸出.
package com.yczuoxin.demo.optional;
import java.util.Optional;
public class OptionalTest {
public static void main(String[] args) {
User user = new User("zhangsan",18);
User empty = null;
System.out.println(Optional.ofNullable(user).map(user1 -> user1.getName()).map(name -> name.toUpperCase()));
System.out.println(Optional.ofNullable(empty).map(user1 -> user1.getName()).map(name -> name.toUpperCase()));
}
}
測試成功.可以看見,如果使用of方法,會報出空指針異常.
4. 年齡大於20的用戶則輸出其用戶名.
package com.yczuoxin.demo.optional;
import java.util.Optional;
public class OptionalTest {
public static void main(String[] args) {
User zhangsan = new User("zhangsan",18);
User lisi = new User("lisi",21);
Optional<String> zhangsanName = Optional.ofNullable(zhangsan).filter(user -> user.getAge() > 20)
.map(user -> user.getName());
System.out.println(zhangsanName);
Optional<String> lisiName = Optional.ofNullable(lisi).filter(user -> user.getAge() > 20)
.map(user -> user.getName());
System.out.println(lisiName);
}
}
測試成功.輸出了年齡大於20的用戶的姓名.