简体   繁体   中英

java-8 optional double checking

I like java-8's optional chaning style. So I want check double null.

class A {
    public String getSome() {
        return ""; // some string
    }
}

class B {
    public String getSome() {
        return ""; // some string
    }
}
class T {
    A a;
    B b;

    public String result() {
        if (a.getSome() != null) {
            if (b.getSome() != null) {
                return a+b;
            } else {
                throw new RuntimeException();
            }
        } else {
            throw new RuntimeException();
        }
    }
}

How can I convert T.result() to Optional Style?

I tried this style but IDE told me 'cyclic interface'.

public String result() {
        return Optional.ofNullable(a.getSome())
                .map(a -> {
                    return Optional.ofNullable(b.getSome())
                            .map(b -> {
                                return a + b;
                            })
                            .orElseThrow(RuntimeException::new);
                })
                .orElseThrow(RuntimeException::new);
    }

While @Eran gave a possible solution, I don't think you add simplicity by using chaining and Optionals.

The new Java 8 API and features must not be a replacement for all pre-Java 8 code. There's a lot of questions for example about using Stream to perform some tasks while a simple for loop would do the trick.

In your case since you only want to check if the reference is not null , simply do:

public String result() {
    return Objects.requireNonNull(a.getSome()) + Objects.requireNonNull(b.getSome());   
}

This should be much simpler :

public String result() {
    return Optional.ofNullable(a.getSome()).orElseThrow(RuntimeException::new) +
           Optional.ofNullable(b.getSome()).orElseThrow(RuntimeException::new);
}

And if you change the getSome methods to return an Optional<String> , the result method would be even simpler :

public String result() {
    return a.getSome().orElseThrow(RuntimeException::new) +
           b.getSome().orElseThrow(RuntimeException::new);
}

However, if it's possible that either a or b themselves would be null , you need some extra code to handle that.

Rewriting your method in what you call "Optional style" would result in the following monstrosity:

Optional.ofNullable(a.getSome())
  .flatMap(x -> 
    Optional.ofNullable(b.getSome()).map(x::concat)
  ).orElseThrow(RuntimeException::new)

Why in the world would you want to do this? You are trying to solve a problem that doesn't exist. Please just follow ZouZou's suggestion and use requireNonNull , but put each requireNonNull in a separate line to make stack traces easier to decipher.

What your IDE complained about is probably your use of a and b as both variables in the method and also as parameter names in the lambdas. You are not allowed to do that.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM