2016-09-16 25 views
3

Java 8 Streamsの簡単な例を理解したいと思います。私は無料のタクシーを返すこのコードを持っています。私はtaxisのリストを反復forループからJava 8ストリームへの例

private List<Taxi> taxis = new ArrayList<Taxi>(); 

Taxi scheduleTaxi(){ 
    for (Taxi taxi : taxis) { 
     if (taxi.isFree()) { 
      return taxi; 
     } 
    } 
    return null; 
} 

、およびtaxi点かの条件を評価する:私は、Java 8つのストリームを使用する同等のコードでループのためにこれを交換したいと思います。条件が適用される場合は、ループを停止してtaxiを返します。

提案がありますか?

+2

'return taxis.stream()。filter(Taxi :: isFree).findFirst()。orElse(null);'。最後のものは 'Stream'メソッドではなく' Optional'メソッドです。 – Andreas

+3

'Stream'を使用する場合、Andreasは正しいですが、おそらく' orElse(null) 'を省略し、代わりに[' Optional '](https://docs.oracle.com /javase/8/docs/api/java/util/Optional.html)。これは、['ifPresent'](https://docs.oracle.com/javase/8/docs/api/)のような便利なメソッドを提供するのでjava/util/Optional.html#ifPresent-java.util.function.Consumer-) – 4castle

+0

@ 4castle [長い回答](http://stackoverflow.com/a/39540979/5221149)を書くことにしました。あなたの提案。 – Andreas

答えて

7

あなたが探していることはこれです:ここでは

return taxis.stream() 
      .filter(Taxi::isFree) 
      .findFirst() 
      .orElse(null); 

がその戻り値の型とのjavadocからのリンクを有する発現ステップのリストです:

式ステップ         | タイプ                     | 代替
taxis                           | List<Taxi>
stream()                       | Stream<Taxi>     | parallelStream()
filter(Taxi::isFree) | Stream<Taxi>
findFirst()                 | Optional<Taxi> | findAny()
orElse(null)               | Taxi                   | filter(Taxi::isFree)呼び出しがmethod referenceを使用している


の下どれも、見ません。
またlambda expressionを使用して書くことができる。

filter(t -> t.isFree()) 

又はラムダ式ブロック使用:

filter(t -> { 
    return t.isFree(); 
}) 

のパラメータは、より明示的であることが、タイプを指定することができる:

filter((Taxi t) -> { return t.isFree(); }) 

これは、anonymous classのように見えますmentioned in a comment 4castle @として

filter(new Predicate<Taxi>() { 
    @Override 
    public boolean test(Taxi t) { 
     return t.isFree(); 
    } 
}) 

、あなたのscheduleTaxi()方法の必要性に応じて、あなたはそれを呼び出し元に明示的にそれことを確認するために、戻り値の型を変更し、最後のステップをスキップする場合がありますにトンタクシーを見つけることができない可能性があります。

Optional<Taxi> scheduleTaxi() { 
    return taxis.stream().filter(Taxi::isFree).findFirst(); 
} 
+0

これはOPコードと同じですが、テキストには無料のタクシーを見つけることだけが記載されています。無作為性があり、タクシーのリストがかなり大きい場合、パラレルストリームと 'findAny'メソッドと' findFirst'メソッドの使用はいくらかの値を持つかもしれません。 –

+0

@AaronDavisこれは、 'parallelStream()'と 'findAny()'を* alternatives *としている理由ですが、表示されるプライマリコールは元のコードに直接当てはまります。私はさまざまな方法のjavadocを読んで、自分自身の違いについて学ぶために、この答えの読者にそれを残しています。彼らは、StackOverflowで質問を作成することができます。そして、これらの違いについて*具体的な質問があります。 – Andreas

+0

ハ..私はそれがあなたの答えの後半にあったことを忘れてしまった。そうすれば、私の電話で完全に読まなくても、答えにコメントすることができます:-) –

0

コメントはちょっとすでにそれを言ったが、私は少しより多くを説明します:ここで

private List<Taxi> taxis = new ArrayList<Taxi>(); 
Optional<Taxi> optTaxi = taxis.stream().filter(taxi -> taxi.isFree()).findFirst() //or findAny() 

は、論理的に何が起こるかです:あなたのリストからのストリームを取得した後、あなたはfilterを使用し、基本的な条件をとります、リスト内のどのアイテムがそれらのアイテムに一致しているかをチェックし、これらのアイテムだけのストリームを返します。次にfindFirst/Anyは最初の/任意の項目を取得し、Optionalとして返します。フィルタリングで「生き残る」項目がない場合、Optionalにはnullが含まれます。

ストリームの動作が異なるため、コードの実行順序が同じではないことにご注意ください。 filter(...).filter(...).filter(...)を実行すると、何度も何度も繰り返すことはありません。戻るあなたのコードに

:あなたはOptional<Taxi>自体を返すか、それを解凍して、必要なものに応じてnullすることができTaxiオブジェクトを返すことができます。

9

最新のIntelliJ IDEA 2016.3 EAP(Community EditionまたはUltimateエディション)を使用すると、自動的に変換することができます。ちょうどあなたのforループの上にカーソルを置く:

Idea

プレス ")のFindFirst(と交換し、" Alt-Enterキーを選択:

Idea

出来上がりは、それが行われています!

Idea

免責事項:私はのIntelliJ IDEAの開発者です。

関連する問題