Ambil elemen pertama yang cocok dengan kriteria

121

Bagaimana cara mendapatkan elemen pertama yang cocok dengan kriteria dalam aliran? Saya sudah mencoba ini tetapi tidak berhasil

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

Kriteria tersebut tidak berfungsi, metode filter dipanggil di kelas selain 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;
}

}
pengguna2147674
sumber

Jawaban:

214

Ini mungkin yang Anda cari:

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



Sebuah contoh:

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

Outputnya adalah:

At the first stop at Station1 there were 250 passengers in the train.
ifloop
sumber
Bisakah Anda memberi saya contoh untuk Kriteria? Ini harus mewakili sesuatu seperti untuk (Stop s: listofstops) {if (s.name.equals ("Linz") return r}
user2147674
1
Berhenti adalah kelas lain, filter metode dipanggil di Kereta tetapi saya ingin berjalan melalui semua elemen Stop dari penghentian SortedSet
user2147674
2
Ternyata saya salah - aliran malas mencegah inefisiensi: stackoverflow.com/questions/23696317/…
Skychan
2
@alexpx dapat Anda gunakan .findFirst().orElse(yourBackUpGoesHere);. Itu juga bisa menjadi nol .findFirst().orElse(null);
ifloop
1
@iammrmehul No. findFirst()mengembalikan objek Opsional ( JavaDoc ), yang mungkin kosong. Dalam hal ini panggilan ke get()akan melempar NPE. Untuk mencegah hal itu terjadi, gunakan orElse()sebagai ganti get()dan berikan objek fallback (seperti orElse(new Station("dummy", -1)), atau simpan hasil dari findFirst()dalam variabel dan periksa dengan isEmpty()sebelum memanggilget()
ifloop
7

Saat Anda menulis ekspresi lambda, daftar argumen di sebelah kiri ->dapat berupa daftar argumen yang diberi tanda kurung (mungkin kosong), atau pengenal tunggal tanpa tanda kurung apa pun. Namun dalam bentuk kedua, pengidentifikasi tidak dapat dideklarasikan dengan nama tipe. Jadi:

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

adalah sintaks yang salah; tapi

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

benar. Atau:

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

juga benar jika kompilator memiliki cukup informasi untuk mengetahui jenisnya.

ajb
sumber
Dengan yang kedua, saya mendapat pesan "create local var" s
user2147674
@ user2147674 Apakah itu pesan kesalahan? Atau apakah kompilator hanya memberi tahu Anda bahwa ia membuat semacam "variabel lokal" baru suntuk digunakan dengan lambda? Ini tidak benar-benar terlihat seperti kesalahan bagi saya, tetapi saya tampaknya tidak menggunakan kompiler yang sama seperti Anda.
ajb
1
@ user2147674 Itu sangat aneh. Saya dapat menggunakan contoh kedua (dengan findFirst().get()diterapkan setelah filter), dan saya tidak mendapatkan kesalahan apa pun. Contoh ketiga juga berhasil untuk saya.
ajb
3

Saya pikir ini cara terbaik:

this.stops.stream().filter(s -> Objects.equals(s.getStation().getName(), this.name)).findFirst().orElse(null);
Martin Volek
sumber