ดึงองค์ประกอบแรกที่ตรงกับเกณฑ์


122

วิธีรับองค์ประกอบแรกที่ตรงกับเกณฑ์ในสตรีม ฉันได้ลองแล้ว แต่ไม่ได้ผล

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

}

คำตอบ:


215

นี่อาจเป็นสิ่งที่คุณกำลังมองหา:

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.

ขอตัวอย่าง Criteria หน่อยได้ไหม ควรเป็นตัวแทนของ (Stop s: listofstops) {if (s.name.equals ("Linz") return r}
user2147674

1
หยุดเป็นคลาสอื่นตัวกรองเมธอดถูกเรียกใช้ใน Train แต่ฉันต้องการเดินผ่านองค์ประกอบ Stop ทั้งหมดของ SortedSet stops
user2147674

2
ปรากฎว่าฉันคิดผิด - สตรีมขี้เกียจป้องกันการไร้ประสิทธิภาพ: stackoverflow.com/questions/23696317/…
Skychan

2
@alexpfx คุณสามารถ.findFirst().orElse(yourBackUpGoesHere);ใช้ได้ ซึ่งอาจเป็นโมฆะได้เช่นกัน .findFirst().orElse(null);
ifloop

1
@iammrmehul No. findFirst()ส่งคืนอ็อบเจ็กต์ทางเลือก ( JavaDoc ) ซึ่งอาจว่างเปล่า ในกรณีนี้การเรียกร้องget()จะโยน NPE เพื่อป้องกันไม่ให้เกิดขึ้นให้ใช้orElse()แทนget()และระบุอ็อบเจ็กต์ทางเลือก (เช่นorElse(new Station("dummy", -1)) หรือเก็บผลลัพธ์ของfindFirst()ตัวแปรและตรวจสอบisEmpty()ก่อนที่จะโทรget()
ifloop

7

เมื่อคุณเขียนนิพจน์แลมบ์ดารายการอาร์กิวเมนต์ทางด้านซ้ายของ->อาจเป็นรายการอาร์กิวเมนต์ในวงเล็บ (อาจว่างเปล่า) หรือตัวระบุเดียวโดยไม่มีวงเล็บใด ๆ แต่ในรูปแบบที่สองไม่สามารถประกาศตัวระบุด้วยชื่อชนิดได้ ดังนั้น:

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

ยังถูกต้องหากคอมไพเลอร์มีข้อมูลเพียงพอที่จะหาประเภท


สำหรับอันที่สองฉันได้รับข้อความ "create local var" s
user2147674

@ user2147674 นั่นคือข้อความแสดงข้อผิดพลาดหรือไม่ หรือคอมไพเลอร์เพิ่งแจ้งให้คุณทราบว่ากำลังสร้าง "ตัวแปรท้องถิ่น" การเรียงลำดับใหม่sเพื่อใช้กับแลมบ์ดา? ดูเหมือนไม่ใช่ข้อผิดพลาดสำหรับฉันจริงๆ แต่ดูเหมือนว่าฉันไม่ได้ใช้คอมไพเลอร์เดียวกันกับคุณ
ajb

1
@ user2147674 มันแปลกมาก ฉันสามารถใช้ตัวอย่างที่สอง (โดยfindFirst().get()ใช้หลังfilter) และไม่ได้รับข้อผิดพลาดใด ๆ ตัวอย่างที่สามก็ใช้ได้ผลกับฉันเช่นกัน
ajb

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.