深入理解 lambda表达式 与 Optional Null 源码解析(Java11 三)
程序员文章站
2022-05-21 16:24:20
一、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