JDK8中Optional几种使用姿势

文章目录
  1. 1. of/empty/ofNullable
  2. 2. get/isPresent
  3. 3. orElse/orElseGet/orElseThrow
  4. 4. 其他实例
    1. 4.1. - fiter/map
    2. 4.2. - Optional转集合
  5. 5. 在说点什么

Optiona 是 JDK1.8 中的一个很流弊的新特性,每个接触JAVA的都遇到过 NPE(NullPointerException),1.8中Optiona帮助我们很好的避免了这一现象,借助源码一步步讲解 Optional 和使用场景

of/empty/ofNullable

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
@Test
public void test1() {

Student student = null;// student 是一个 空对象

/**
* 源码:
* public static <T> Optional<T> of(T value) {//of会创建一个 实例化一个 Optional
* return new Optional<>(value);
* }
*
* private Optional(T value) { //检查value是否为null
* this.value = Objects.requireNonNull(value);
* }
*
* public static <T> T requireNonNull(T obj) { //不做解释了...
* if (obj == null)
* throw new NullPointerException();
* return obj;
* }
*
* 解释: 如果对象为Null使用of会抛出java.lang.NullPointerException
*/
Optional<Student> op1 = Optional.of(student);

Optional<Student> op2 = Optional.empty();//看API就知道啥意思了,基本没什么太大卵用

/**
* 源码:
* public static <T> Optional<T> ofNullable(T value) {
* return value == null ? empty() : of(value);
* }
* 解释: 如果对象为空就返回 empty() 相反就 调用 of(value);
*/
Optional<Student> op3 = Optional.ofNullable(student);
}

get/isPresent

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
@Test
public void test2() {

Optional<Student> op = Optional.ofNullable(null);//创建一个对象为Null的Optional

/**
* 源码:
* public boolean isPresent() {
* return value != null;
* }
* 解释: 因为 value == null 源码是 value != null 因此返回false
*/
System.out.println(op.isPresent());

/**
* 源码:
* public T get() {
* if (value == null) {
* throw new NoSuchElementException("No value present");
* }
* return value;
* }
* 解释: 如果 value 为空 null 抛出 NoSuchElementException 否则返回 T
*/
System.out.println(op.get());
}

orElse/orElseGet/orElseThrow

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
@Test
public void test3() {

Student student = null;

/**
* 源码:
* public T orElseGet(Supplier<? extends T> other) {
* return value != null ? value : other.get();
* }
* 解释: 对象为空返回null,否则返回对象
*/
Student s1 = Optional.ofNullable(student).orElseGet(Student::new);

System.out.println(s1);//Student{id=null, name='null', email='null', age=null}

/**
* 源码:
* public T orElse(T other) {
* return value != null ? value : other;
* }
* 解释: 如果 T 为null则返回一个默认值
*/
Student s2 = (Student) Optional.ofNullable(student).orElse(new Student(1L, "枫", "1837307557@qq.com", 22));
System.out.println(s2);//Student{id=1, name='枫', email='1837307557@qq.com', age=22}

/**
* 源码:
* public <X extends Throwable> T orElseThrow(Supplier<? extends X> exceptionSupplier) throws X {
* if (value != null) {
* return value;
* } else {
* throw exceptionSupplier.get();
* }
* }
* 解释: 如果T为null那么抛出异常(本宝宝非常喜欢)
*/
Student s3 = Optional.ofNullable(student).orElseThrow(() -> new RuntimeException("哈哈,报错了吧"));
System.out.println(s3);//抛出:java.lang.RuntimeException: 哈哈,报错了吧

}

其他实例

- fiter/map

1
2
3
4
5
6
7
8
9
10
11
@Test
public void test4() {

//可以加if判断条件过滤
String filter = Optional.ofNullable("aadasdsa").filter((value) -> value.length() > 5).get();
System.out.println(filter);

//大小写转换等等..
String map = Optional.ofNullable("aadasdsa").map(String::toUpperCase).get();
System.out.println(map);
}

- Optional转集合

将一个Optional转为List或者Set

Optional是一个集合,虽然里面只有0或者1个元素,但它一样是一个集合。如果要转为List或者Set,一般的写法可以是:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
public static <T> List<T> toList(Optional<T> option) {
return option.
map(Collections::singletonList).
orElse(Collections.emptyList());
}

或者更传统的写法:

public static <T> List<T> toList(Optional<T> option) {
if (option.isPresent())
return Collections.singletonList(option.get());
else
return Collections.emptyList();
}

但是在java8里,其实只需要这么写:

import static java.util.stream.Collectors.*;
//转为List
List<String> list = collect(opt, toList());
//转为Set
Set<String> set = collect(opt, toSet());

在说点什么

程序猿要与时俱进,JDK9都快出了你难道还要守着6和7吗,当你认为JDK8有BUG的时候你可曾知道当初JDK6-7也是这样过来的…

对本章有建议的可以在下方留言,会第一时间修改