Tìm nạp phần tử đầu tiên phù hợp với tiêu chí


121

Làm cách nào để lấy phần tử đầu tiên phù hợp với tiêu chí trong luồng? Tôi đã thử điều này nhưng không hiệu quả

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

Tiêu chí đó không hoạt động, phương thức lọc được gọi trong một lớp khác với Dừng.

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

}

Câu trả lời:


213

Đây có thể là những gì bạn đang tìm kiếm:

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



Một ví dụ:

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

Đầu ra là:

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

Bạn có thể cho tôi một ví dụ về Tiêu chí được không? Nó phải đại diện cho một cái gì đó giống như for (Stop s: listofstops) {if (s.name.equals ("Linz") return r}
user2147674

1
Dừng là một lớp, bộ lọc phương pháp được invokaded trong tàu nhưng tôi muốn đi qua tất cả các yếu tố Dừng của SortedSet dừng
user2147674

2
Hóa ra tôi sai - luồng lười biếng ngăn chặn sự kém hiệu quả: stackoverflow.com/questions/23696317/…
Skychan

2
@alexpfx bạn có thể sử dụng .findFirst().orElse(yourBackUpGoesHere);. Đó cũng có thể là rỗng .findFirst().orElse(null);
ifloop

1
@iammrmehul No. findFirst()trả về một đối tượng Tùy chọn ( JavaDoc ), có thể trống. Trong trường hợp này, lệnh gọi tới get()sẽ ném NPE. Để ngăn chặn điều đó xảy ra, sử dụng orElse()thay vì get()và cung cấp một đối tượng dự phòng (như orElse(new Station("dummy", -1)), hoặc lưu trữ kết quả của findFirst()một biến và kiểm tra xem nó có isEmpty()trước khi gọiget()
ifloop

7

Khi bạn viết một biểu thức lambda, danh sách đối số ở bên trái ->có thể là danh sách đối số được đặt trong ngoặc đơn (có thể trống) hoặc một số nhận dạng không có bất kỳ dấu ngoặc đơn nào. Nhưng ở dạng thứ hai, định danh không thể được khai báo bằng tên kiểu. Như vậy:

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

không đúng cú pháp; nhưng

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

đúng. Hoặc là:

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

cũng đúng nếu trình biên dịch có đủ thông tin để tìm ra các loại.


Với cái thứ hai, tôi nhận được thông báo "tạo địa chỉ var" s
user2147674

@ user2147674 Đó có phải là thông báo lỗi không? Hay là trình biên dịch chỉ thông báo cho bạn rằng nó đang tạo một loại "biến cục bộ" mới sđể sử dụng với lambda? Nó không thực sự giống như một lỗi đối với tôi, nhưng tôi dường như không sử dụng cùng một trình biên dịch như bạn.
ajb

1
@ user2147674 Điều đó khá lạ. Tôi có thể sử dụng ví dụ thứ hai (có findFirst().get()áp dụng sau filter) và tôi không gặp bất kỳ lỗi nào. Ví dụ thứ ba cũng phù hợp với tôi.
ajb

3

Tôi nghĩ đây là cách tốt nhất:

this.stops.stream().filter(s -> Objects.equals(s.getStation().getName(), this.name)).findFirst().orElse(null);
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.