欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

深入理解 lambda表达式 与 Optional Null 源码解析(Java11 三)

程序员文章站 2022-12-05 13:08:51
一、Optional出现的缘由 二、深入理解 Value based Classes 三、Optional容器的构造 四、普通方法 五、高级拓展 1、ifPresent(Consumer) 2、ifPresentOrElse(Consumer) 3、filter(Predicate) 4、or(Su ......
import org.junit.test;
import org.junit.runner.runwith;
import org.springframework.boot.test.context.springboottest;
import org.springframework.test.context.junit4.springrunner;

import java.util.*;
import java.util.function.function;
import java.util.function.supplier;
import java.util.stream.collectors;
import java.util.stream.stream;


/**
 * @author 陈杨
 */


@runwith(springrunner.class)
@springboottest
public class optionaltest {


    @test

    public void testoptional() {

一、optional出现的缘由

/*
 *   a container object which may or may not contain a non-{@code null} value.
 *
 *   一个装泛型为t的 值容器 可以包含null  以规避 空指针异常
 *   public final class optional<t>
 */

二、深入理解 value-based classes

/*
 *   value-based classes
 *
 *   https://docs.oracle.com/javase/8/docs/api/java/lang/doc-files/valuebased.html
 *
 *   final  immutable (但里面可以包含指向 可变对象的引用)
 *   具有equals、hashcode和tostring的实现  仅从实例的状态计算 而不是从其标识或任何其他对象或变量的状态计算
 *   不使用身份敏感的操作,例如实例之间的引用相等(==) 实例的hashcode,或实例的内部锁(intrinsic lock)同步
 *   判断是否相等 仅比较equals()方法  而非对象的引用(==)
 *   没有可访问的构造函数   通过工厂方法实例化,不保证实例创建的一致性(不一定是单例)
 *
 *   基于值的对象  没有public的构造方法  比较值是否相等(不比较引用)
 */

三、optional容器的构造

//    private static final optional<?> empty = new optional<>();
//    private final t value;

//    constructs an empty instance.
//    private optional() { this.value = null; }


/*
 *    constructs an instance with the described value.
 *
 *    private optional(t value) {  this.value = objects.requirenonnull(value); }
 */



/*
 *    returns an empty {@code optional} instance.  no value is present for this {@code optional}.
 *
 *       public static<t> optional<t> empty() {
 *           @suppresswarnings("unchecked")
 *            optional<t> t = (optional<t>) empty;
 *                 return t;
 *                 }
 */
optional<list<string>> empty = optional.empty();


/*    构造一个容器里不为 null 的容器对象
 *
 *    public static <t> optional<t> of(t value) { return new optional<>(value);  }
 */
optional<list<string>> optional = optional.of(arrays.aslist("kirito", "love", "asuna"));


/*     构造一个容器里可能为 null 的容器对象
 *
 *     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;
 *           }
 */
system.out.println("---------------------------------------\n");
system.out.println("optional容器中存在的值:" + optional.get());


//     判断 容器中存在值 返回true
//     public boolean ispresent() { return value != null; }
system.out.println("---------------------------------------\n");
system.out.println("optional容器中存在值:" + optional.ispresent());
system.out.println("empty容器中存在值:" + empty.ispresent());


//     判断 容器中不存在值 返回true
//     @since   11
//     public boolean isempty() { return value == null; }
system.out.println("---------------------------------------\n");
system.out.println("optional容器中不存在值:" + optional.isempty());
system.out.println("empty容器中不存在值:" + empty.isempty());

五、高级拓展

1、ifpresent(consumer)

/*
 *     如果存在 value 对 value 进行一个 consumer消费
 *     public void ifpresent(consumer<? super t> action) {
 *                  if (value != null) {
 *                   action.accept(value);
 *                  }
 *      }
 *
 */
system.out.println("---------------------------------------\n");
system.out.println("optional容器中存在值就进行consumer消费(打印输出)");
optional.ifpresent(system.out::println);

2、ifpresentorelse(consumer)

/*    如果存在 value 对 value 进行一个 consumer消费  不存在 执行emptyaction(empty-based action)
 *    @since 9
 *    public void ifpresentorelse(consumer<? super t> action, runnable emptyaction) {
 *             if (value != null) {
 *              action.accept(value);
 *             } else {
 *                emptyaction.run();
 *             }
 *    }
 */
system.out.println("---------------------------------------\n");
system.out.println("容器中存在值就打印值,不存在打印 hello world");
optional.ifpresentorelse(system.out::println, () -> system.out.println("hello world"));
empty.ifpresentorelse(system.out::println, () -> system.out.println("hello world"));

3、filter(predicate)

/*
 *     如果存在value  且符合预期predicate 则对 value 进行预期操作predicate.test(value) 否则返回empty
 *     public optional<t> filter(predicate<? super t> predicate) {
 *                objects.requirenonnull(predicate);
 *                if (!ispresent()) {
 *                  return this;
 *                } else {
 *                return predicate.test(value) ? this : empty();
 *                }
 *      }
 */
system.out.println("---------------------------------------\n");
system.out.println("遍历集合元素");
optional.filter(strings -> {
    strings.foreach(system.out::println);
    return true;
});

4、or(supplier)

/*
 *      如果存在value 则返回value  否则使用supplier接口的get()方法 构造出一个optional
 *      @since 9
 *      public optional<t> or(supplier<? extends optional<? extends t>> supplier) {
 *             objects.requirenonnull(supplier);
 *                if (ispresent()) {
 *                 return this;
 *                } else {
 *              @suppresswarnings("unchecked")
 *                optional<t> r = (optional<t>) supplier.get();
 *                    return objects.requirenonnull(r);
 *                }
 *        }
 */
system.out.println("---------------------------------------\n");
supplier<optional<list<string>>> sup =
        () -> optional.ofnullable(arrays.aslist("optional", "or", "supplier"));

system.out.println(empty.or(sup));

5、stream.of(value)

/*
 *      如果存在value 则返回stream.of(value)  否则返回一个stream.empty()
 *      @since 9
 *      public stream<t> stream() {
 *             if (!ispresent()) {
 *             return stream.empty();
 *              } else {
 *             return stream.of(value);
 *             }
 *      }
 */
system.out.println("---------------------------------------\n");
system.out.println("以stream流 遍历optional容器内的值");
stream<list<string>> stream = stream.of(optional.get());
stream.foreach(system.out::println);

6、orelse(t other)

/*
 *      如果存在value 则返回value  否则返回t other
 *      public t orelse(t other) {
 *             return value != null ? value : other;
 *         }
 */
system.out.println("---------------------------------------\n");
system.out.println("  容器中存在值就返回值 不存在就返回{\"hello\",\"world\"}");
system.out.println(empty.orelse(arrays.aslist("hello", "world")));

7、orelseget(supplier)

/*
 *       如果存在value 则返回value  否则返回supplier接口实现
 *       public t orelseget(supplier<? extends t> supplier) {
 *                return value != null ? value : supplier.get();
 *        }
 */
system.out.println("---------------------------------------\n");
supplier<list<string>> listsupplier = () -> arrays.aslist("do", "orelseget");
system.out.println(empty.orelseget(listsupplier));

8、orelsethrow

/*
 *       如果存在value 则返回value  否则抛出异常nosuchelementexception
 *       @since 10
 *       public t orelsethrow() {
 *            if (value == null) {
 *             throw new nosuchelementexception("no value present");
 *              }
 *         return value;
 *        }
 */
system.out.println("---------------------------------------\n");
system.out.println("  容器中存在值就返回值 不存在就返回nosuchelementexception");

system.out.println(optional.orelsethrow());
try {
    system.out.println(empty.orelsethrow());
} catch (nosuchelementexception e) {
    system.out.println(" nosuchelementexception ---> no value present");
}

9、orelsethrow(supplier)

/*
 *      如果存在value 则返回value  否则使用supplier接口生成一个被抛出的exceptionsupplier -->exception
 *      public <x extends throwable> t orelsethrow(supplier<? extends x> exceptionsupplier) throws x {
 *                        if (value != null) {
 *                             return value;
 *                            } else {
 *                    throw exceptionsupplier.get();
 *                        }
 *        }
 */
system.out.println("---------------------------------------\n");
supplier<nosuchelementexception> nosuchelementexception = nosuchelementexception::new;

try {
    system.out.println(empty.orelsethrow(nosuchelementexception));
} catch (nosuchelementexception e) {
    system.out.println(" supplier nosuchelementexception ---> no value present");
}

10、map(function)

/*
 *
 *      如果存在value 则返回value并作为mapper的输入 将其输出作为新的value存放至optional  否则返回一个null的optional
 *      如果经过mapper 后得到的结果为null  返回一个null的optional
 *      mapper函数若为null 则抛出nullpointerexception
 *      map:对集合中每个元素进行操作
 *
 *
 *      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));
 *                    }
 *       }
 */
system.out.println("---------------------------------------\n");
function<list<string>, list<string>> function =
        up -> up.stream().map(string::touppercase).collect(collectors.tolist());
optional<list<string>> o = optional.map(function);
system.out.println(o.get());

11、flatmap(function)

        /*
         *      如果存在value 则返回value并作为mapper的输入 将其输出作为新的value存放至optional  否则返回一个null的optional
         *      如果经过mapper 后得到的结果为null  返回一个null的optional
         *      mapper函数若为null 则抛出nullpointerexception
         *
         *      与map的方法的区别:
         *      map
         *
         *     return optional.ofnullable(mapper.apply(value));
         *
         *      flatmap
         *
         *      optional<u> r = (optional<u>) mapper.apply(value);
         *      return objects.requirenonnull(r);
         *      flatmap:对集合中每个元素进行操作然后再扁平化
         *
         *
         *       public <u> optional<u> flatmap(function<? super t, ? extends optional<? extends u>> mapper) {
         *                     objects.requirenonnull(mapper);
         *                             if (!ispresent()) {
         *                                 return empty();
         *                                } else {
         *                  @suppresswarnings("unchecked")
         *                 optional<u> r = (optional<u>) mapper.apply(value);
         *                   return objects.requirenonnull(r);
         *                             }
         *        }
         */
        system.out.println("---------------------------------------\n");
        function<list<string>, optional<list<string>>> func =
                up -> optional.of(up.stream().map(string::touppercase).collect(collectors.tolist()));
        optional<list<string>> u = optional.flatmap(func);
        system.out.println(u.get());

    }

}

六、测试

  .   ____          _            __ _ _
 /\\ / ___'_ __ _ _(_)_ __  __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
 \\/  ___)| |_)| | | | | || (_| |  ) ) ) )
  '  |____| .__|_| |_|_| |_\__, | / / / /
 =========|_|==============|___/=/_/_/_/
 :: spring boot ::        (v2.1.2.release)

2019-02-01 18:29:34.870  info 17140 --- [           main] com.java.design.java8.optionaltest       : starting optionaltest on desktop-87rmbg4 with pid 17140 (started by 46250 in e:\ideaprojects\design)
2019-02-01 18:29:34.871  info 17140 --- [           main] com.java.design.java8.optionaltest       : no active profile set, falling back to default profiles: default
2019-02-01 18:29:35.437  info 17140 --- [           main] com.java.design.java8.optionaltest       : started optionaltest in 0.775 seconds (jvm running for 1.574)
---------------------------------------

optional容器中存在的值:[kirito, love, asuna]
---------------------------------------

optional容器中存在值:true
empty容器中存在值:false
---------------------------------------

optional容器中不存在值:false
empty容器中不存在值:true
---------------------------------------

optional容器中存在值就进行consumer消费(打印输出)
[kirito, love, asuna]
---------------------------------------

容器中存在值就打印值,不存在打印 hello world
[kirito, love, asuna]
hello world
---------------------------------------

遍历集合元素
kirito
love
asuna
---------------------------------------

optional[[optional, or, supplier]]
---------------------------------------

以stream流 遍历optional容器内的值
[kirito, love, asuna]
---------------------------------------

  容器中存在值就返回值 不存在就返回{"hello","world"}
[hello, world]
---------------------------------------

[do, orelseget]
---------------------------------------

  容器中存在值就返回值 不存在就返回nosuchelementexception
[kirito, love, asuna]
 nosuchelementexception ---> no value present
---------------------------------------

 supplier nosuchelementexception ---> no value present
---------------------------------------

[kirito, love, asuna]
---------------------------------------

[kirito, love, asuna]

process finished with exit code 0