Original: Taste of Little Sister (wechat official ID: XjjDog), welcome to share, please reserve the source. Any reprint that does not retain this statement is plagiarism.

Java Optional is very useful. We usually use Optional for non-null processing, leaving out if processing. The main purpose is to solve the notorious null-pointer exception in Java.

For example, in ordinary coding, we often encounter non-null judgment of input parameters.

public void getXXX(Map<String, String> params) {
    Map<String, String> map = params;
    if (map == params) {
        map = newHashMap<>(); }}Copy the code

Too much of this code, and our program will slowly turn into shit mountain. At this point you can transform with Optional.

public void getXXX(Map<String, String> params) {
    Map<String, String> map = Optional.ofNullable(params).orElse(new HashMap<>());
}
Copy the code

Fewer lines of code, clearer logic, and lower performance :).

1. Complex examples

Let’s do a more complicated example.

Let’s say we need a deeper level of data.

String cityCode = customer.getAddress().getCity().getCityCode().substring(0.3);
Copy the code

This doesn’t make sense, because one of these rings, which might be null, would throw a null pointer. So, we need to go through layers of judgment.

public void getCityCode(Customer customer) {
    String cityCode = "000";
    if(customer ! =null) {
        Address address = customer.getAddress();
        if (null! = address) { City city = address.getCity();if(city ! =null) {
                String code = city.getCityCode();
                if (null! = code && code.length() >=3) {
                    cityCode = code.substring(0.3);
                }
            }
        }
    }
    System.out.println(cityCode);
}
Copy the code

Using Optional lambda syntax, we can change the code to look like this:

public void getCityCode(Customer customer) {
    String cityCode = Optional.ofNullable(customer)
            .map(c -> c.getAddress())
            .map(a -> a.getCity())
            .map(c -> c.getCityCode())
            .filter(s -> s.length() >= 3)
            .map(s -> s.substring(0.3))
            .orElse("000");
}
Copy the code

Does the code look good?

Although appearance level is high, still point below slant a few key content of the door.

2. Optional private content

In fact, guava had a similar tool long before Java8 was released (2014), but since lambda syntax was not available at the time, it was limited to simple applications.

Guava’s Optional supports serialization, which can be returned in RPC framework methods, but is rarely used.

Java’s Optional doesn’t serialize at all. Why java8 Optional don’t implement serialization, here is a discussion, can see mail.openjdk.java.net/pipermail/j…

In addition, Java8 has more methods than Guava, such as ifPresent, map, filter, flatMap, and orElseThrow. Given how few people use Guava Optional these days, it’s worth mentioning.

Optional can put some pressure on the GC. If you are developing the underlying framework, you should be careful to use it. Netty has tested it and finally abandoned Optional.

But I still like to use it. Why are most of the country Cruder?

3. What is the word “Try”?

Using Javaer encoded in Java for a long time, you will have an amazing feeling when you see languages like Scala and Kotlin. But these bags are too big, the introduction of a certain cost, can only be greedy for their body.

However, the Java standard library has relatively limited API support for functional programming. Is there a lightweight way to enhance our Java libraries? It would be even better if it could be combined with Lambda expressions. Vavr is just such a simple Jar package that makes our code much smoother to write.

Its Maven coordinates are:

<dependency>
    <groupId>io.vavr</groupId>
    <artifactId>vavr</artifactId>
    <version>0.10.3</version>
</dependency>
Copy the code

Here’s the code for a great sleep sequencing:

public class SleepSort implements Runnable {
    private int num;
    public SleepSort(int num) {
        this.num = num;
    }
    @Override
    public void run(a) {
        try {
            Thread.sleep(num * 10);
        } catch (Exception e) {
            e.printStackTrace();
        }
        System.out.print(num + "");
    }
    public static void main(String[] args) {
        int[] nums = {5.22.10.7.59.3.16.4.11.8.14.24.27.25.26.28.23.99};
        Arrays.stream(nums).forEach(n->new Thread(newSleepSort(n)).start()); }}Copy the code

The Run part is too much useless information, we can use Try to modify.

We can simplify it to the following two lines:

Try.run(()->Thread.sleep(num*10))
        .andThen(()->System.out.print(num + ""));
Copy the code

It supports a wide range of methods and can do most of the subsequent business processing. For example, in the onFailure method, add logging of exception messages.

Common Jackson JSON processing can be simplified into the following code:

String json = Try.of(() -> objectMapper.writeValueAsString(str)).getOrElse("{}");
Copy the code

That’s why Try works so well. On top of that, vAVR is just over 800 kilobytes in size.

4. More operations on VAVR

Vavr supports Tuple, Option, Try, Either, set convenience, multivariate functions, curring, and more.

You can look at the VAVR version of if Else. Here is the code for the four branches. All these weird symbols in there, it’s just grammatical sugar.

public String vavrMatch(String input) {
    return Match(input).of(
            Case($("a"), "a1"),
            Case($("b"), "b2"),
            Case($("c"), "c3"),
            Case($(), "unknown")); }Copy the code

For example, if you want to define a Function instead of a class, you can use Function in Java. Unfortunately, Java Function only supports one argument.

Function with Vavr supports up to 22 parameters!

Or say you want to return multiple values in a method. This, which is easy to implement in Python, would have to define a Class to receive in Java.

Tuples can support combinations of multiple return values. For example:

// (Java, 8)
Tuple2<String, Integer> java8 = Tuple.of("Java".8); 

// "Java"
String s = java8._1; 

/ / 8
Integer i = java8._2; 
Copy the code

Vavr supports returning eight values at a time.

Then there are gadgets like lazy. Such as delayed fetching values.

Lazy<Double> lazy = Lazy.of(Math::random);
lazy.isEvaluated(); // = false
lazy.get();         // = 0.123 (random generated)
lazy.isEvaluated(); // = true
lazy.get();         / / = 0.123 (memoized)
Copy the code

There are many such extensions. But the ones I use most often are trys and tuples. It makes the code more elegant and the intent clearer.

Oh. Resilience4j makes heavy use of VAVR, the fuse component that was officially recommended after Hystrix stopped updating.

Xjjdog is a public account that doesn’t allow programmers to get sidetracked. Focus on infrastructure and Linux. Ten years architecture, ten billion daily flow, and you discuss the world of high concurrency, give you a different taste. My personal wechat xjjdog0, welcome to add friends, further communication.