preface

I used Java 8 to write a paragraph of logic, but my colleague said I didn’t understand it. Here is the business background, we can have a look!

! [I had written in Java 8 a logic, colleagues call don’t understand, you give it a try] (https://p6-tt.byteimg.com/origin/pgc-image/383b3af2412b485494b5fe91ef4e4566?from=pc)

Business background

First of all, the business requirements are as follows: all orders are pulled from the third-party e-commerce platform and saved to the company’s own database. We need to determine whether there is logistics information, and if there is, we need to upload it again.

However, the data returned by the third-party interface is in JSON format, in which the logistics information is deeply hidden. As shown below, the JSON node looks like this:

xxxOrder > xxxShippingInfo > xxxShipmentDetails > xxxTrackingInfo > trackingNumber, trackingLink

Basic implementation

Because the data returned by the third-party interface is in JSON format, the JSON string needs to be converted into a Java object for processing.

@jsonIgnoreProperties (ignoreUnknown = true)public class XxxOrder {/** ** logistics information */ @jsonProperty ("shippingInfo") private XxxShippingInfo xxxShippingInfo; }Copy the code

The above is only the first layer example. In order to get logistics information, four layers of objects need to be encapsulated successively. To really get logistics information, null Pointers need to be avoided, and four layers need to be judged to get it, as shown in the example:

if(xxxOrder ! = null){ if(xxxOrder.getXxxShippingInfo() ! = null){ if(xxxOrder.getXxxShippingInfo().getXxxShipmentDetails() ! = null){ if(xxxOrder.getXxxShippingInfo().getXxxShipmentDetails().getXxxTrackingInfo() ! = null){ ... }}}}Copy the code

Getting a logistics information is so much trouble, I am also drunk, it is not elegant to write.

Java 8 implementation

Since I knew Java 8 could handle this type of requirement, I never thought of implementing it in the most primitive way, but just implemented it in Java 8:

/*** /private String[] getFulfillments(XxxOrder xxxOrder) { return Optional.ofNullable(xxxOrder) .map((o) -> o.getXxxShippingInfo()) .map((si) -> si.getXxxShipmentDetails()) .map((sd) -> sd.getXxxTrackingInfo()) .map((t) -> new String[]{t.getTrackingNumber(), t.getTrackingLink()}) .orElse(null); }Copy the code

After r finishing writing, my colleagues actually call straight don’t understand, but also specially ran to ask me.

Realize the principle of

Java 8 Optional is used to avoid null Pointers. If you don’t understand, you can check out the article here.

Optional#map method to implement this logic principle, see the map implementation source code:

public<U> Optional<U> map(Function<? super T, ? extends U> mapper) {    // 函数式接口不能为null    Objects.requireNonNull(mapper);    // 如果当前没有值,返回一个空的Optional    if (!isPresent())        return empty();    else {        // 如果当前有值,返回一个函数式处理该值的结果Optional        return Optional.ofNullable(mapper.apply(value));    }}// 判断 Optional Value 有没有值public boolean isPresent() {    return value != null;}// 创建一个 Optional,可以为空public static <T> Optional<T> ofNullable(T value) {    return value == null ? empty() : of(value);}
Copy the code

So back to this program:

/ / the root object is empty just create an empty Optional, or create a root object OptionalOptional. OfNullable (xxxOrder) / / root object for empty return empty Optional directly, Otherwise return the value optional. map((o) -> o.gexxxShippingInfo ()) // and so on... .map((si) -> si.getXxxShipmentDetails()) .map((sd) -> sd.getXxxTrackingInfo()) .map((t) -> new String[]{t.trackingNumber (), t.trackingLink ()}) // Return null. }Copy the code

Maybe you read the feeling or do not understand, I admit, really quite around, not quite good to understand, this can only be understood can not be spoken, read more practice will understand.

The key kernel of this is that when we call map, we return the empty Optional if the Optional has no value, we don’t call the functional interface, so we don’t get a null pointer. So as long as one is empty, logistics information can not be obtained behind.

The program uses a.xx.xx.xx chain call. The map method must be Optional, and map returns Optional.

One problem is, if they’re all empty, aren’t all maps going to go through? Does it affect performance in this case? Does the compiler optimize? We don’t know yet.

There is also a flatMap method. What’s the difference?

! [I had written in Java 8 a logic, colleagues call don’t understand, you give it a try] (https://p3-tt.byteimg.com/origin/pgc-image/f4980b6d210a460a8375eecd34beefa5?from=pc)

The flatMap return result needs to be wrapped in the Optional return in a functional interface, which is not appropriate here.

conclusion

A lot of people talk about learning new Java 8 features all the time, but in my opinion, most of them don’t do it and use the original implementation.

In fact, I have been trying to learn this knowledge, the latest one is Java 14, and I have been sharing a series of new feature articles.

Therefore, although I am now an old wave, I feel that I have come to a lot of waves ahead in learning and mastering new knowledge.

The last

You can leave a comment below to discuss what you don’t understand. Thanks for watching. Think the article is helpful to you remember to pay attention to me a thumbs-up support!