【问题标题】:Fetch first element of stream matching the criteria获取匹配条件的流的第一个元素
【发布时间】:2014-05-21 08:22:09
【问题描述】:

如何在流中获取符合条件的第一个元素?这个我试过了,还是不行

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

}

【问题讨论】:

    标签: java java-8 java-stream


    【解决方案1】:

    这可能是您正在寻找的:

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

    更好的是,如果有可能不匹配任何元素,在这种情况下get() 将抛出 NPE。所以使用:

    yourStream
        .filter(/* your criteria */)
        .findFirst()
        .orElse(null); /* You could also create a default object here */
    


    一个例子:
    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()
                .orElse(null);
    
        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 }
    • Stops 是另一个类,方法过滤器在 Train 中调用,但我想遍历 SortedSet 站点的所有 Stop 元素
    • 原来我错了 - 懒惰的流可以防止效率低下:stackoverflow.com/questions/23696317/…
    • @alexpfx 你可以使用.findFirst().orElse(yourBackUpGoesHere);。也可以是 null .findFirst().orElse(null);
    • @iammrmehul No. findFirst() 返回一个可选对象 (JavaDoc),该对象可能为空。在这种情况下,对get() 的调用将抛出 NPE。为了防止这种情况发生,请使用orElse() 而不是get() 并提供一个备用对象(如orElse(new Station("dummy", -1)),或者将findFirst() 的结果存储在一个变量中并在调用get() 之前使用isEmpty() 检查它
    【解决方案2】:

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

    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 这是一条错误消息吗?还是编译器只是通知您它正在创建一种新的“局部变量”s 以与 lambda 一起使用?对我来说,这看起来并不像一个错误,但我显然没有使用与你相同的编译器。
    • @user2147674 这很奇怪。我可以使用第二个示例(在filter 之后应用findFirst().get()),并且我没有收到任何错误。第三个例子也适用于我。
    【解决方案3】:

    我认为这是最好的方法:

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2018-07-24
      • 2020-12-03
      • 1970-01-01
      • 2013-01-10
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多