기준과 일치하는 첫 번째 요소를 가져옵니다.


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 2014-04-08

1
Stops는 또 다른 클래스입니다. 메서드 필터는 Train에서 호출되지만 SortedSet 정류장의 모든 Stop 요소를 살펴보고 싶습니다
user2147674 2014

2
내가 틀렸다는 것이 밝혀졌습니다-게으른 스트림은 비 효율성을 방지합니다 : stackoverflow.com/questions/23696317/…
Skychan

2
@alexpfx를 사용할 수 있습니다 .findFirst().orElse(yourBackUpGoesHere);. 그것은 또한 null .findFirst().orElse(null);
ifloop

1
@iammrmehul No. findFirst()는 비어있을 수있는 선택적 개체 ( JavaDoc )를 반환합니다 . 이 경우를 호출 get()하면 NPE가 발생합니다. 이런 일이 발생하지 않도록 orElse()대신 대신 사용 get()하여 대체 객체 (예 orElse(new Station("dummy", -1)findFirst()isEmpty()get()
:)

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"메시지가 나타납니다.
user2147674 2014

@ user2147674 오류 메시지입니까? 아니면 컴파일러 s가 람다와 함께 사용할 새로운 종류의 "로컬 변수" 를 생성하고 있다는 사실을 알려주 나요? 나에게 실제로 오류처럼 보이지는 않지만 분명히 당신과 같은 컴파일러를 사용하고 있지 않습니다.
ajb 2014

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.