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?
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.
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.
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.
As for your getters, don't use Optional. And try to design your classes so none of the members can possibly be null.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With