Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java 8 optional add return result only if optional.isPresent

I have a piece of code where an interface has an Optional return method and some of the classes that implement it to return something, other don't.

In an effort to embrace this brilliant "null killer", here is what I have tried:

public interface Gun {
    public Optional<Bullet> shoot();
}

public class Pistol implements Gun{
    @Override
    public Optional<Bullet> shoot(){
        return Optional.of(this.magazine.remove(0)); 
    }//never mind the check of magazine content
}

public class Bow implements Gun{
    @Override
    public Optional<Bullet> shoot(){
        quill--;
        return Optional.empty();
    }
}

public class BallisticGelPuddy{
    private Gun[] guns = new Gun[]{new Pistol(),new Bow()};
    private List<Bullet> bullets = new ArrayList<>();
    public void collectBullets(){
        //here is the problem
        for(Gun gun : guns)
            gun.shoot.ifPresent(bullets.add( <the return I got with the method>)
}}

I apologise for how silly this example is.
How can I check the return I just got and add it only if present, using optional?

P.S. is there any real usefulness to Optional which is if(X != null) couldn't do?

like image 359
Vale Avatar asked Jun 15 '16 21:06

Vale


People also ask

How do you set the value of an Optional object in Java?

You can create an Optional object using the of() method, which will return an Optional object containing the given value if the value is non-null, or an empty Optional object if the value is null.

What does Optional isPresent do?

The isPresent() method of java. util. Optional class in Java is used to find out if there is a value present in this Optional instance. If there is no value present in this Optional instance, then this method returns false, else true.

What is difference between isPresent and ifPresent?

isPresent() returns true if the given Optional object is non-empty. Otherwise it returns false. Optional. ifPresent() performs given action if the given Optional object is non-empty.

Should Java 8 getters return Optional type?

As for your getters, don't use Optional. And try to design your classes so none of the members can possibly be null.


1 Answers

I see where you're going with this - when a projectile (may be a better class name than Bullet) goes through BallisticGelPuddy, it either becomes stuck or it doesn't. If it gets stuck, it accumulates in BallisticGelPuddy.

Let's rewrite the code if we were using null checks instead:

for(Gun gun: guns) {
    final Bullet bullet = gun.shoot();
    if(bullet != null) {
        bullets.add(bullet);
    }
}

Pretty straightforward, right? If it exists we want to add it in.

Let's add the optional style back in:

for(Gun gun: guns) {
    gun.shoot().ifPresent(bullets::add);
}

Effectively these two things accomplish the same thing, although the Optional approach is terser.

In this scenario, there's really no difference between the two approaches since you're always going to be checking for existence. Optional is meant to guard against mistakes when handling null and allows you to express a more fluid call chain, but consider the practicality of using Optional in this scenario. It doesn't seem entirely necessary for this case.

like image 90
Makoto Avatar answered Oct 13 '22 00:10

Makoto