获取符合条件的第一个元素


121

如何获取与流中的条件匹配的第一个元素?我已经尝试过了但是没用

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

该条件不起作用,在除Stop之外的其他类中调用filter方法。

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

}

Answers:


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年

1
Stops是另一类,方法过滤器在Train中涉及,但我想遍历SortedSet停靠点的所有Stop元素
user2147674 2014年

2
事实证明我错了-懒流防止效率低下:stackoverflow.com/questions/23696317/...
Skychan

2
您可以使用@alexpfx .findFirst().orElse(yourBackUpGoesHere);。也可以为 .findFirst().orElse(null);
ifloop

1
@iammrmehul编号findFirst()返回可选对象(JavaDoc),该对象可能为空。在这种情况下,对的调用get()将引发NPE。为了防止这种情况的发生,请使用orElse()代替get()并提供一个备用对象(如orElse(new Station("dummy", -1)),或将结果存储findFirst()在变量中并isEmpty()在调用之前进行检查get()
ifloop

7

当您编写lambda表达式时,其左侧的参数列表->可以是带括号的参数列表(可能为空),也可以是不带括号的单个标识符。但是在第二种形式中,不能使用类型名称声明标识符。从而:

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

如果编译器具有足够的信息来找出类型,则也是正确的。


随着第二个,我得到一个消息“创建局部变量” S
user2147674

@ user2147674这是错误消息吗?还是编译器只是通知您它正在创建一种新的s用于lambda 的“局部变量” ?在我看来,这似乎并不是一个错误,但是我显然没有使用与您相同的编译器。
2014年

1
@ user2147674这很奇怪。我可以使用第二个示例(在findFirst().get()之后加上filter),并且不会出现任何错误。第三个例子也对我有用。
2014年

3

我认为这是最好的方法:

this.stops.stream().filter(s -> Objects.equals(s.getStation().getName(), this.name)).findFirst().orElse(null);
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.