当前位置:网站首页>Optional classes, convenience functions, creating options, optional object operations, and optional streams
Optional classes, convenience functions, creating options, optional object operations, and optional streams
2022-06-21 09:36:00 【tragically unhappy】
java.util.optional
Preface
We must consider what happens when we get elements in an empty stream , We are always used to the fact that the flow is uninterrupted . However , Place... In the stream null But it can be easily interrupted , So can there be an object , This allows us to hold the stream elements while , You can also give us friendly hints when the element does not exist ( No exceptions )?
One 、 Optional class
Optional Can achieve such a function . Some of the standard stream operations can return Optional object , Because they don't guarantee the expected results .
findFirst(): Returns the... Containing the first element Optional object , If the stream is empty, returnOptional.empty.findAny(): Returns... Containing any element Optional object , If the stream is empty, returnOptional.empty.max()andmin(): Returns a value containing the maximum or minimum value Optional object , If the stream is empty, returnOptional.empty.
reduce() No more with identity Form begins , Instead, include its return value in Optional in .(identity Objects become other forms of reduce() The default result of , So there is no risk of an empty result ) For digital streams IntStream etc. ,average() The results will be packaged in Optional To prevent the flow from being empty .
public class OptionalsFromEmptyStreams {
public static void main(String[] args) {
System.out.println(Stream.<String>empty()
.findFirst());
System.out.println(Stream.<String>empty()
.findAny());
System.out.println(Stream.<String>empty()
.max(String.CASE_INSENSITIVE_ORDER));
System.out.println(Stream.<String>empty()
.min(String.CASE_INSENSITIVE_ORDER));
System.out.println(Stream.<String>empty()
.reduce((s1, s2) -> s1 + s2));
System.out.println(IntStream.empty()
.average());
}
}
/* output: Optional.empty Optional.empty Optional.empty Optional.empty Optional.empty OptionalDouble.empty */
When the stream is empty, you get a Optional.empty object , Instead of throwing an exception .Optional Have toString() Methods can be used to present useful information .
Be careful : Air flow is through Stream.<String>empty() Created . If you call... Without any context Stream.empty(),Java Don't know its data type .
Here is Optional The basic usage of :
public class OptionalBasics {
static void test(Optional<String> optString) {
if (optString.isPresent())
System.out.println(optString.get());
else
System.out.println("Nothing inside!");
}
public static void main(String[] args) {
test(Stream.of("Epithets").findFirst());
test(Stream.<String>empty().findFirst());
}
}
/* output: Epithets Nothing inside! */
When you receive Optional Object time , Should be First call isPresent() Check if it contains elements , If there is , You can use get() obtain .
Two 、 Convenience functions
There are many convenience functions to unpack Optional ,
isPresent(Consumer): Call when the value exists Consumer, Otherwise, do nothing .orElse(otherObject): If the value exists, it will return , Otherwise it generates otherObject.orElseGet(Supplier): If only exists, it will directly return , Otherwise use Supplier Function to generate an alternative object .orElseThrow(Supplier): If the value exists, return , Otherwise use Supplier Function generates an exception .
public class Optionals {
static void basics(Optional<String> optString) {
if (optString.isPresent()) {
System.out.println(optString.get());
} else System.out.println("Nothing Inside!");
}
static void ifPresent(Optional<String> optString) {
optString.ifPresent(System.out::println);
}
static void orElse(Optional<String> optString) {
System.out.println(optString.orElse("Nada"));
}
static void orElseGet(Optional<String> optString) {
System.out.println(optString.orElseGet(() -> "Generated"));
}
static void orElseThrow(Optional<String> optString) {
try {
System.out.println(optString.orElseThrow(() -> new Exception("Supplied")));
} catch (Exception e) {
System.out.println("Caught " + e);
}
}
static void test(String testName, Consumer<Optional<String>> cos) {
System.out.println("===" + testName + "=====");
cos.accept(Stream.of("Epithets").findFirst());
cos.accept(Stream.<String>empty().findFirst());
}
public static void main(String[] args) {
test("basics", Optionals::basics);
test("ifPresent", Optionals::ifPresent);
test("orElse", Optionals::orElse);
test("orElseGet", Optionals::orElseGet);
test("orElseThrow", Optionals::orElseThrow);
}
}
/* output: ===basics===== Epithets Nothing Inside! ===ifPresent===== Epithets ===orElse===== Epithets Nada ===orElseGet===== Epithets Generated ===orElseThrow===== Epithets Caught java.lang.Exception: Supplied */
3、 ... and 、 establish Optional
When we add Optional when , You can use the following three static methods :
empty(): Generate an empty Optional.of(value): Wrap a non null value to Optional in .ofNullable(): For a value that may be empty , Automatically generated for space time Optional.empty, Otherwise, wrap the value in Optional in .
Here is an example :
public class CreatingOptionals {
static void test(String testName, Optional<String> optional) {
System.out.println("====" + testName + "====");
System.out.println(optional.orElse("NULL"));
}
public static void main(String[] args) {
test("empty", Optional.empty());
test("of", Optional.of("Howdy()"));
try {
test("of", Optional.of(null));
} catch (Exception e) {
System.out.println(e);
}
test("ofNullable", Optional.ofNullable("Hi"));
test("ofNullable", Optional.ofNullable(null));
}
}
/* output: ====empty==== NULL ====of==== Howdy() java.lang.NullPointerException ====ofNullable==== Hi ====ofNullable==== NULL */
We can't pass null To of() To create Optional object , The safest way is : Use ofNullable() To handle it gracefully null.
Four 、 Optional The object operation :filter、map、flatMap
When our flow pipe produces Optional object , The following three methods can make Optional The follow-up can do more operations :
filter(Predicate): Yes Optional Content application in Predicate And return the result . If Optional dissatisfaction Predicate , take Optional Turn to empty Optional. If Optional It's empty , Then return to null directly Optional.map(Function): If Optional Not empty , application Function On Optional The content in , And return the result . Otherwise go straight back to Optional.empty.flatMap(Function): Same as map(), But the provided mapping function ( Namely Function) Wrap the results in Optional In the object , therefore flatMap() No packaging at the end .
public class OptionalFilter {
static String[] elements = {
"Foo", "Bar", "Baz", "Bingo"};
static Stream<String> testStream() {
return Arrays.stream(elements);
}
static void test(String descr, Predicate<String> predicate) {
System.out.println("---(" + descr + ")----");
for (int i = 0; i <= elements.length; i++) {
System.out.println(testStream()
.skip(i)
.findFirst()
.filter(predicate));
}
}
public static void main(String[] args) {
test("true", s -> true);
test("false", s -> false);
test("s != \"\"", s -> s != "");
// Here s.length() Is an incoming single stream element
test("s.length() == 3", s -> s.length() == 3);
test("startsWith(\"B\")", s -> s.startsWith("B"));
}
}
/* output: ---(true)---- Optional[Foo] Optional[Bar] Optional[Baz] Optional[Bingo] Optional.empty ---(false)---- Optional.empty Optional.empty Optional.empty Optional.empty Optional.empty ---(s != "")---- Optional[Foo] Optional[Bar] Optional[Baz] Optional[Bingo] Optional.empty ---(s.length() == 3)---- Optional[Foo] Optional[Bar] Optional[Baz] Optional.empty Optional.empty ---(startsWith("B"))---- Optional.empty Optional[Bar] Optional[Baz] Optional[Bingo] Optional.empty */
Even if the output looks like a stream , Pay special attention to test() Medium for loop :1. Every time for Loops operate on newly generated streams ,2. Skip the specified number of elements ,3. By calling findFirst() Get the first of the remaining elements , And package it in Optional In the object .
Be careful : This is different from ordinary for loop , there be equal to Number actually makes the last bit out of the range of the stream that the array is converted to , But it doesn't go wrong .
Same as map() equally ,Optional.map() Only in the Optional This mapping function is executed only when it is not empty , And will Optional Extract the content of , Passed to the mapping function .
public class OptionalMap {
static String[] elements = {
"12", "", "23", "45"};
static Stream<String> stream() {
return Arrays.stream(elements);
}
static void test(String descr, Function<String,String> func) {
System.out.println("---(" + descr + ")----");
for (int i = 0; i <= elements.length; i++) {
System.out.println(stream()
.skip(i)
.findFirst()// A optional
.map(func));
}
}
public static void main(String[] args) {
test("Add brackets", s -> "[" + s + "]");
test("Increment", s -> {
try {
return Integer.parseInt(s) + 1 + "";
} catch (Exception e) {
return s;
}
});
test("Replace", s -> s.replace("2", "9"));
// Remember every s Is a single flow element
test("Take last digit", s -> s.length() > 0 ? s.charAt(s.length() - 1) + "" : s);
}
}
/* output: ---(Add brackets)---- Optional[[12]] Optional[[]] Optional[[23]] Optional[[45]] Optional.empty ---(Increment)---- Optional[13] Optional[] Optional[24] Optional[46] Optional.empty ---(Replace)---- Optional[19] Optional[] Optional[93] Optional[45] Optional.empty ---(Take last digit)---- Optional[2] Optional[] Optional[3] Optional[5] Optional.empty */
The return result of the mapping function is automatically packaged as Optional.Optional.empty() ( empty ) It will be skipped directly .
public class OptionalFlatMap {
static String[] elements = {
"12","", "23", "45"};
static Stream<String> stream() {
return Arrays.stream(elements);
}
static void test(String descr, Function<String, Optional<String>> func) {
System.out.println("---(" + descr + ")----");
for (int i = 0; i <= elements.length; i++) {
System.out.println(stream()
.skip(i)
.findFirst()
.flatMap(func));// The parameter here becomes Optional type
}
}
public static void main(String[] args) {
test("Add brackets", new Function<String, Optional<String>>() {
@Override
public Optional<String> apply(String s) {
return Optional.of("[" + s + "]");
}
});
test("Increment",s -> {
try {
return Optional.of(Integer.parseInt(s) + 1 + "");
} catch (Exception e) {
return Optional.of(s);
}
});
test("Replace", s -> Optional.ofNullable(s.replace("2", "9")));
test("Take last digit",s->Optional.of(s.length()>0?s.charAt(s.length()-1)+"":s));
}
}
/* output: ---(Add brackets)---- Optional[[12]] Optional[[]] Optional[[23]] Optional[[45]] Optional.empty ---(Increment)---- Optional[13] Optional[] Optional[24] Optional[46] Optional.empty ---(Replace)---- Optional[19] Optional[] Optional[93] Optional[45] Optional.empty ---(Take last digit)---- Optional[2] Optional[] Optional[3] Optional[5] Optional.empty */
Optional Of flatMap() Apply to generated Optional The mapping function of , So it won't be like map() That encapsulates the results in Optional in .
Same as map(),flatMap() Non empty... Will be extracted Optional Content applies it to mapping functions . The only difference is that it no longer wraps the results in Optional in , Because it has been packed .
5、 ... and 、 Optional flow
Suppose your generator might produce null value . So when you use it to create a stream , use Optional It's better to wrap the elements .
public class Signal {
private final String msg;
public Signal(String msg) {
this.msg = msg;
}
public String getMsg() {
return msg;
}
@Override
public String toString() {
return "Signal{" +
"msg='" + msg + '\'' +
'}';
}
static Random rand = new Random(47);
public static Signal morse() {
switch (rand.nextInt(4)) {
case 1:
return new Signal("dot");
case 2:
return new Signal("dash");
default:
return null;
}
}
public static Stream<Optional<Signal>> stream() {
return Stream.generate(Signal::morse)
.map(signal -> Optional.ofNullable(signal));
}
}
When we use this stream , You have to figure out how to unpack Optional . The code is as follows :
public class StreamOfOptionals {
public static void main(String[] args) {
Signal.stream()
.limit(10)
.forEach(System.out::println);
System.out.println("-----------");
Signal.stream()
.limit(10)
.filter(Optional::isPresent)
.map(Optional::get)
.forEach(System.out::println);
}
}
/* output: Optional[Signal{msg='dash'}] Optional[Signal{msg='dot'}] Optional[Signal{msg='dash'}] Optional.empty Optional.empty Optional[Signal{msg='dash'}] Optional.empty Optional[Signal{msg='dot'}] Optional[Signal{msg='dash'}] Optional[Signal{msg='dash'}] ----------- Signal{msg='dot'} Signal{msg='dot'} Signal{msg='dash'} Signal{msg='dash'} */
Here we use filter() To keep those non empty Optional, And then in map() Use in get() Get elements . Because every situation needs to be defined “ Null value ” The meaning of , So we usually take a different approach for each application .
边栏推荐
- stm32mp1 Cortex M4开发篇11:扩展板蜂鸣器控制
- equals 和 hashCode
- \Processing method of ufeff
- Shortcut keys accumulated when using various software
- Ali has been working for 8 years. This learning note is left when he reaches P8. He has helped his friends get 10 offers
- Wechat applet
- R language uses the names function to modify the name of the data column variable, modify the name of the specified data column, and maintain the original data column name for the unmodified data colu
- Judge the data type of JS
- ArCore支持的设备
- The @transactional in JUnit disappears. Can @rollback test the flag of rollback?
猜你喜欢

stm32mp1 Cortex M4开发篇8:扩展板LED灯控制实验

Solve the problem of error when typescript object gets value

Wechat applet
![[vs], [usage problem], [solution] when VS2010 is opened, it stays in the startup interface](/img/04/a7455760caa4fc0480a034de1e24b8.png)
[vs], [usage problem], [solution] when VS2010 is opened, it stays in the startup interface

stm32mp1 Cortex M4开发篇13:扩展板按键外部中断
![[actual combat] STM32 FreeRTOS porting series Tutorial 4: FreeRTOS software timer](/img/16/ad38288689f629106a19a0b8defea2.jpg)
[actual combat] STM32 FreeRTOS porting series Tutorial 4: FreeRTOS software timer

还在直接用localStorage么?全网最细:本地存储二次封装(含加密、解密、过期处理)

【实战】STM32MP157开发教程之FreeRTOS系统篇6:FreeRTOS 列表和列表项

A command starts the monitoring journey!

Introduction and template of segment tree Foundation (I)
随机推荐
stm32mp1 Cortex M4开发篇8:扩展板LED灯控制实验
stm32mp1 Cortex M4开发篇11:扩展板蜂鸣器控制
Request and response must know
Junit5 unit test
Summary of Web automated testing
115. secondary packaging of table components
应用配置管理,基础原理分析
嵌入式远程岗位、兼职、接单、众包平台
[practice] STM32 FreeRTOS migration series tutorial 5:freertos message queue
R language uses the names function to modify the name of the data column variable, modify the name of the specified data column, and maintain the original data column name for the unmodified data colu
Lei niukesi --- basis of embedded AI
Adapt to the pits in Huawei models
Unity vuforia recommended equipment
TC software detailed design document (mobile group control)
Full stack development
Electron checks the CPU and memory performance when the module is introduced
The internal structure of MySQL and how an SQL statement is executed
音视频格式简介、编解码、音视频同步
【实战】STM32 FreeRTOS移植系列教程5:FreeRTOS消息队列
如何选择嵌入式练手项目、嵌入式开源项目大全