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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/22940416/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-13 19:28:16  来源:igfitidea点击:

Fetch first element which matches criteria

javajava-8java-stream

提问by user2147674

How to get first element that matches a criteria in a stream? I've tried this but doesn't work

如何获取与流中的条件匹配的第一个元素?我试过这个但不起作用

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

That criteria is not working, the filter method is invoked in an other class than Stop.

该标准不起作用,过滤器方法是在 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;
}

}

采纳答案by ifloop

This might be what you are looking for:

这可能是您正在寻找的:

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



An example:



一个例子:

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

Output is:

输出是:

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

回答by ajb

When you write a lambda expression, the argument list to the left of ->can be either a parenthesized argument list (possibly empty), or a single identifierwithout any parentheses. But in the second form, the identifier cannot be declared with a type name. Thus:

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

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

is incorrect syntax; but

是不正确的语法;但

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

is correct. Or:

是正确的。或者:

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

is also correct if the compiler has enough information to figure out the types.

如果编译器有足够的信息来确定类型也是正确的。

回答by Martin Volek

I think this is best way:

我认为这是最好的方法:

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