基準に一致する最初の要素を取得します


121

ストリームの基準に一致する最初の要素を取得するにはどうすればよいですか?私はこれを試しましたが動作しません

this.stops.stream().filter(Stop s-> s.getStation().getName().equals(name));

その基準が機能しておらず、フィルターメソッドがStop以外のクラスで呼び出されています。

public class Train {

private final String name;
private final SortedSet<Stop> stops;

public Train(String name) {
    this.name = name;
    this.stops = new TreeSet<Stop>();
}

public void addStop(Stop stop) {
    this.stops.add(stop);
}

public Stop getFirstStation() {
    return this.getStops().first();
}

public Stop getLastStation() {
    return this.getStops().last();
}

public SortedSet<Stop> getStops() {
    return stops;
}

public SortedSet<Stop> getStopsAfter(String name) {


    // return this.stops.subSet(, toElement);
    return null;
}
}


import java.util.ArrayList;
import java.util.List;

public class Station {
private final String name;
private final List<Stop> stops;

public Station(String name) {
    this.name = name;
    this.stops = new ArrayList<Stop>();

}

public String getName() {
    return name;
}

}

回答:


213

これはあなたが探しているものかもしれません:

yourStream
    .filter(/* your criteria */)
    .findFirst()
    .get();



例:

public static void main(String[] args) {
    class Stop {
        private final String stationName;
        private final int    passengerCount;

        Stop(final String stationName, final int passengerCount) {
            this.stationName    = stationName;
            this.passengerCount = passengerCount;
        }
    }

    List<Stop> stops = new LinkedList<>();

    stops.add(new Stop("Station1", 250));
    stops.add(new Stop("Station2", 275));
    stops.add(new Stop("Station3", 390));
    stops.add(new Stop("Station2", 210));
    stops.add(new Stop("Station1", 190));

    Stop firstStopAtStation1 = stops.stream()
            .filter(e -> e.stationName.equals("Station1"))
            .findFirst()
            .get();

    System.out.printf("At the first stop at Station1 there were %d passengers in the train.", firstStopAtStation1.passengerCount);
}

出力は次のとおりです。

At the first stop at Station1 there were 250 passengers in the train.

基準の例を教えてください。for(Stop s:listofstops){if(s.name.equals( "Linz")return r}
user2147674

1
Stopsは別のクラスです。メソッドフィルターはTrainで呼び出されますが、SortedSetストップのすべてのStop要素をウォークスルーしたいと思います
user2147674

2
: -私は間違っ判明怠惰なストリームは非効率防ぐstackoverflow.com/questions/23696317/...
Skychan

2
@alexpfxを使用できます.findFirst().orElse(yourBackUpGoesHere);。それもnullに なる可能性があります.findFirst().orElse(null);
ifloop

1
@iammrmehul No. findFirst()は、空の可能性があるOptionalオブジェクト(JavaDoc)を返します。この場合、への呼び出しget()はNPEをスローします。これが発生しないようにするorElse()にはget()、の代わりにを使用してフォールバックオブジェクト(などorElse(new Station("dummy", -1))を提供するかfindFirst()、変数の結果を保存して、isEmpty()呼び出す前に確認しますget()
ifloop

7

ラムダ式を記述する場合、の左側の->引数リストは、括弧で囲まれた引数リスト(空の場合もある)、または括弧なしの単一の識別子のいずれかになります。ただし、2番目の形式では、識別子を型名で宣言することはできません。したがって:

this.stops.stream().filter(Stop s-> s.getStation().getName().equals(name));

構文が正しくありません。だが

this.stops.stream().filter((Stop s)-> s.getStation().getName().equals(name));

正しい。または:

this.stops.stream().filter(s -> s.getStation().getName().equals(name));

コンパイラーが型を理解するのに十分な情報を持っている場合も正しいです。


2番目のものでは、「ローカル
変数を

@ user2147674それはエラーメッセージですか?または、コンパイラsはラムダで使用する新しい種類の「ローカル変数」を作成していることを通知しているだけですか?私には実際にはエラーのようには見えませんが、私はあなたと同じコンパイラを使用していないようです。
ajb 14

1
@ user2147674それはかなり奇妙です。2番目の例を(findFirst().get()後で適用された状態でfilter)使用でき、エラーは発生しません。3番目の例も私にとってはうまくいきます。
ajb 2014

3

私はこれが最善の方法だと思います:

this.stops.stream().filter(s -> Objects.equals(s.getStation().getName(), this.name)).findFirst().orElse(null);
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.