2016-06-15 4 views
5

私は、インターフェイスにオプションのreturnメソッドがあり、何かを返すためにそれを実装するクラスのいくつかがありますが、それ以外のコードはありません。この華麗な「ヌルキラー」を採用する努力においてJava 8オプションadd.result.isPresentの場合にのみ返す戻り値

は、ここで私が試したものです:

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>) 
}} 

私はこの例がどのように愚かなことをお詫び申し上げます。
私はちょうど持って帰って確認して、オプションの場合はそれを使用して追加することができますか?

P.S.任意の本当の有用性はありますか?(X!= null)はできませんでしたか?

+1

"(X!= null)ができなかった場合、オプションには本当に便利ですか?"というメッセージが表示されます。 - 私はOptionalの巨大なファンですが、私はこれをほぼ一種のコメントとみなしています。オプションの型があるときは、そこにはないかもしれないことを自動的に*知る必要があります。しかし、* null *を保持することができるほとんどの値は決して*べきではありません。したがって、ヌルチェックですべての参照解除を絶対に囲むのではありません。 –

+0

@EdwardPeters私は何らかの血行でこれを変えたくないが、私は[ここのこの人](http://huguesjohnson.com/programming/java/java8optional.html)に同意する。私は「ああ、オプションです!」という印象に同意します。確かにそれが存在することを確かめてください。しかし、少し上手くやったかもしれないと思います。 – Vale

+2

私が見る利点の一部は明快です。 'Optional'が' null'値を割り当てられるのを見るたびに、あなたはそれが間違っていることを知っていて、それを修正することで正当だと感じるかもしれません。ヌルが別の値に割り当てられているのを見ると...よく、誰が知っているのでしょう、それはおそらく適切です。私はまた、哲学的には、「何もないかもしれないこと」は、「何かでなければならないもの」とは異なるタイプでなければならないと感じています。もっと上手くやることができましたが、それが基本的な言語の一部であった場合に限り、... IMO、Javaは口紅の3つの部分におよぶ1つの部分の豚です。 –

答えて

5

飛行機(Bulletよりもクラス名が良いかもしれません)がBallisticGelPuddyを通過したとき、それが止まってしまいます。滞留した場合は、BallisticGelPuddyに累積します。

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

を非常に簡単、右:

は、私たちが代わりにnullチェックを使用していた場合のコードを書き直してみましょうか?それが存在する場合、我々はそれを追加したい

のはに戻って、オプションのスタイルを追加してみましょう:。Optionalアプローチはterserですが、効果的にこれら二つのことは、同じことを実現

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

このシナリオでは、常に存在を確認しようとしているため、2つの方法の違いはありません。 Optionalは、nullを処理する際の間違いを防ぐためのもので、express a more fluid call chainを許可しますが、このシナリオではOptionalを使用することの実用性を考慮してください。この場合は完全にとは思われません。あなたが行うことができますストリームAPIで

6

私は、あなたがしたいと思う:

gun.shoot().ifPresent(bullets::add); 

それとも、あまりにも(符号化)ループで済ますことができます。

guns.stream() 
    .map(Gun::shoot) 
    .filter(Optional::isPresent) 
    .map(Optional::get) 
    .forEach(bullets::add); 

しかし、それは醜悪です。

3

、:

List<Bullet> bullets = Arrays.stream(guns) 
      .map(Gun::shoot) 
      .flatMap(this::streamopt) // make Stream from Optional! 
      .collect(Collectors.toList()); 

は残念ながら、Javaの8で、ストリームするOptionalsを変換方法はありませんので、あなたはそれを自分で記述する必要があります。 を参照してくださいUsing Java 8's Optional with Stream::flatMap

0

今後の参考のために、私のような問題に陥っている人のために投稿したいと思います。

public class Bullet{ 
    private int weight = 5; 
    public int getWeight(){ return weigth;} 
} 
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<>(); 
    private int totWeigth = 0; 
    public void collectBullets(){ 
     // IF YOU WANT TO ONLY ADD WHAT YOU HAVE FOUND IN A COMPATIBLE CLASS 
     // thanks to makoto and bohemian for the answers 
     for(Gun gun : guns) 
      gun.shoot.ifPresent(bullets::add) 
     //IF YOU WANT TO ACCESS THE RETURNED OBJECT AND ADD IT TOO 
     for(Gun gun : guns) 
      gun.shoot.ifPresent(arg -> {totWeight += arg.getWeigth(); 
             bullets.add(arg);}); 
}} 
関連する問題