• 首页 首页 icon
  • 工具库 工具库 icon
    • IP查询 IP查询 icon
  • 内容库 内容库 icon
    • 快讯库 快讯库 icon
    • 精品库 精品库 icon
    • 问答库 问答库 icon
  • 更多 更多 icon
    • 服务条款 服务条款 icon

再次学习Optional做的笔记

武飞扬头像
TomCloud
帮助1

学习网站: www.mayikt.com

一、阶段一

1.1 准备工作

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.ToString;
import lombok.experimental.Accessors;

/**
 * @author zx
 * @date 2022年06月07日 8:40
 */
@Data
@NoArgsConstructor
@AllArgsConstructor
@ToString
@Accessors(chain = true)
public class Person {
    /**
     * 姓名
     */
    private String name;

    /**
     * 年龄
     */
    private Integer age;
}

学新通

1.2 初步认识Optional

mport com.mayikt.wikt.optional.domain.Person;
import lombok.extern.slf4j.Slf4j;
import org.junit.Test;

import java.util.Optional;
import java.util.function.Supplier;

/**
 * @author zx
 * @date 2022年06月07日 8:39
 */
@Slf4j
public class OptionalMainTest {
    @Test
    public void testPersonIsNull() throws Throwable {
        Person person = new Person("TOM",34);
        
        //如果person中的name为空,抛出异常
        String name = Optional.ofNullable(person.getName())
                .orElseThrow((Supplier<Throwable>) () -> new RuntimeException("person.name is null"));

        log.info("====>name={}<====",name);

    }
}

学新通

二、阶段二 Optional源码

2.1 Optional对象创建源码

public final class Optional<T> {
   private static final Optional<?> EMPTY = new Optional<>();
   private final T value;
    
   //我们可以看到两个构造方格都是private 私有的
   //说明 我们没办法在外面去new出来Optional对象
   private Optional() {
        this.value = null;
    }
    
   private Optional(T value) {
        this.value = Objects.requireNonNull(value);
    }
    
    //这个静态方法大致 是创建出一个包装值为空的一个对象因为没有任何参数赋值
   public static<T> Optional<T> empty() {
        @SuppressWarnings("unchecked")
        Optional<T> t = (Optional<T>) EMPTY;
        return t;
    }
    
    //这个静态方法大致 是创建出一个包装值非空的一个对象 因为做了赋值
   public static <T> Optional<T> of(T value) {
        return new Optional<>(value);
    }
    
    //这个静态方法大致是 如果参数value为空,则创建空对象,如果不为空,则创建有参对象
   public static <T> Optional<T> ofNullable(T value) {
        return value == null ? empty() : of(value);
    }
 }
学新通

2.2 创建对象代码演示:

/**
 * 创建optional对象
 */
@Test
public void testCreateOptional() {
    // 1、创建一个包装对象值为空的Optional对象
    Optional<String> optEmpty = Optional.empty();

    // 2、创建包装对象值非空的Optional对象 如果为空为抛出异常,
    //改异常是 Objects.requireNonNull(value) 抛出的
    Optional<String> optOf = Optional.of("optional");
    System.out.println(optOf.get());

    // 3、创建包装对象值允许为空也可以不为空的Optional对象
    String str = (String) Optional.ofNullable(null).orElse("of nullable is null ");
    System.out.println("str:"   str);

    Optional<String> optOfNullable2 = Optional.ofNullable("是否为空");
    System.out.println(optOfNullable2.get());

}
学新通

三、阶段三Optional方法使用

3.1 get()方法 获取对象值

返回对象的值

源码:

public T get() {
    if (value == null) {
        throw new NoSuchElementException("No value present");
    }
    return value;
}

示例代码: 如果value不为空则做返回,如果为空则抛出异常 “No value present”

// 2、创建包装对象值非空的Optional对象 如果为空为抛出异常,
//改异常是 Objects.requireNonNull(value) 抛出的
Optional<String> optOf = Optional.of("optional");
System.out.println(optOf.get());

3.2 isPresent()方法 判断是否为空

isPresent()方法就是会返回一个boolean类型值,如果对象不为空则为真,如果为空则false

源码:

public boolean isPresent() {
    return value != null;
}

示例代码:

//判断是否为空,不会空返回true,为空返回false
Person person2 = new Person();
boolean nameIsNull = Optional.ofNullable(person2.getName()).isPresent();
System.out.println("person name is null:" nameIsNull);

3.3 ifPresent()方法是否为空并返回函数

源码:

public void ifPresent(Consumer<? super T> consumer) {
    //如果value不为空,则运行accept方法体
    if (value != null)
        consumer.accept(value);
}

示例代码:

    /**
     * 判断是否为空,如果不为空执行函数
     */
    @Test
    public void testIfPresent(){
        Person person = new Person("tom",34);

        //name 不为空的时候执行打印person中的name值
        Optional.ofNullable(person.getName())
                .ifPresent(name-> System.out.println("person name value:"  name));

    }

3.4 filter()过滤对象

接受一个对象,然后对他进行条件过滤,如果条件符合则返回Optional对象本身,如果不符合则返回空Optional

源码:

public Optional<T> filter(Predicate<? super T> predicate) {
    Objects.requireNonNull(predicate);
    //如果为空直接返回this
    if (!isPresent())
        return this;
    else
    //判断返回本身还是空Optional
        return predicate.test(value) ? this : empty();
}

示例代码: 判断person不为空的情况下,过滤出age>10.

/**
     * filter() 过滤对象
     */
@Test
public void testFilter(){
    //Person person = new Person("tom",12);
    Person person = new Person("tom",112);
    //过滤出age 》 20 ,没有满足返回Optioanl 空对象
    Optional<Person> optionalPerson = Optional
        .ofNullable(person)
        .filter(m -> m.getAge() > 20);

    //不为空的时候打印person对象信息
    optionalPerson.
        ifPresent(p-> System.out.println(p.toString()));
}

学新通

3.5 map()方法对象进行二次包装

map()方法将对应Funcation函数式接口中的对象,进行二次运算,封装成新的对象然后返回

源码:

public<U> Optional<U> map(Function<? super T, ? extends U> mapper) {
    Objects.requireNonNull(mapper);
    //如果为空返回自己
    if (!isPresent())
        return empty();
    else {
        //否则返回用方法修饰过的Optional
        return Optional.ofNullable(mapper.apply(value));
    }
}

示例代码: 如果person不为空获取name:

    /**
     * map()方法 对对象进行二次封装
     */
    @Test
    public void testOptionalMap(){
        Person person = new Person();
        //Optional<String> nameStr = Optional.ofNullable(person).map(Person::getName);
        String nameStr = Optional.ofNullable(person).map(Person::getName).orElse("name is null");
        
        //如果为空: name:Optional.empty
        System.out.println("name:" nameStr);
    }

3.6 flatMap()方法Optional对象进行二次封装

flatMap()方法将对应Optional< Funcation >函数式接口中的对象,进行二次运算,封装成新的对象然后返回在Optional中

flatMap源码:

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));
    }
}

map()方法源码:

public<U> Optional<U> map(Function<? super T, ? extends U> mapper) {
    Objects.requireNonNull(mapper);
    //如果为空返回自己
    if (!isPresent())
        return empty();
    else {
        //否则返回用方法修饰过的Optional
        return Optional.ofNullable(mapper.apply(value));
    }
}

示例代码:

@Test
public void testFlatMap(){
    Person person = new Person();
    Optional<Person> optionalPerson = Optional.ofNullable(person).flatMap(p -> Optional.ofNullable(p));

    System.out.println(optionalPerson);


    Optional<Object> optName = Optional.ofNullable(person)
        .map(p -> Optional.ofNullable(p.getName()).orElse("name为空"));
    System.out.println(optName.get());
}

3.7 orElse()方法为空返回对象

常用方法之一,这个方法意思是如果包装对象为空的话,就执行orElse方法里的value,如果非空,则返回写入对象 源码:

public T orElse(T other) {
    //如果非空,返回value,如果为空,返回other
    return value != null ? value : other;
}

示例代码:

/**
 * `orElse()方法`为空返回对象
 */
@Test
public void testOrElse(){
    Person person = null;
    Person newPerson = Optional.ofNullable(person).orElse(new Person("TOM", 34));

    //Person(name=TOM, age=34)
    System.out.println(newPerson);
}

3.8 orElseGet()方法 为空返回Supplier对象

入参为Supplier对象,为空返回传入对象的.get()方法,如果非空则返回当前对象

源码:

public T orElseGet(Supplier<? extends T> other) {
return value != null ? value : other.get();
}

Suppiler是一个接口,是类似Spring的懒加载,声明之后并不会占用内存,只有执行了get()方法之后,才会调用构造方法创建出对象 创建对象的语法的话就是Supplier supPerson= Person::new;

需要使用时supPerson.get()即可

示例代码:

/**
 * `orElseGet()方法` 为空返回Supplier对象
 * 入参为Supplier对象,为空返回传入对象的`.get()`方法,
 * 如果非空则返回当前对象
 */
@Test
public void testOrElseGet(){
    Person person = null;
    Person newPerson = Optional.ofNullable(person).orElseGet(Person::new);
    log.info("newPerson:{}",newPerson);
}

3.9 orElseThrow()方法为空返回异常

如果为空,就抛出你定义的异常,如果不为空返回当前对象

源码:

public <X extends Throwable> T orElseThrow(Supplier<? extends X> exceptionSupplier) throws X {
    if (value != null) {
        return value;
    } else {
        throw exceptionSupplier.get();
    }
}

示例代码:

/**
 * `orElseThrow()方法`为空返回异常
 */
@Test
public void testOrElseThrow(){
    Person person = null;
    Person newPerson = Optional.ofNullable(person).orElseThrow(() -> new RuntimeException("person is null"));
    log.info("====>person:{}<====",newPerson);
}

四、相似方法对比

4.1 orElse()和orElseGet()和orElseThrow()异同点

三个方法效果类似,如果对象不为空,则返回对象,如果为空,则返回方法体中的对应参数,所以可以看出这三个方法体中参数是不一样的

  • orElse(T 对象)
  • orElseGet(Supplier < T >对象)
  • orElseThrow(异常)

4.2 map()和orElseGet的异同点

方法效果类似,对方法参数进行二次包装,并返回,入参不同

  • map(function函数)
  • flatmap(Optional< function >函数)

这篇好文章是转载于:学新通技术网

  • 版权申明: 本站部分内容来自互联网,仅供学习及演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,请提供相关证据及您的身份证明,我们将在收到邮件后48小时内删除。
  • 本站站名: 学新通技术网
  • 本文地址: /boutique/detail/tanhgegjga
系列文章
更多 icon
同类精品
更多 icon
继续加载