如何重写 Java for 循环,使用流返回匹配元素

问题描述 投票:0回答:2

我想优化我的方法。

我有对象列表,我想对它们进行迭代,将字段与输入进行比较,如果匹配,我想在其他方法中使用第一个对象。比如:

for (ObjTest objTest : listOfObjTest) {
    if (objTest.getField().equals(input.getField()) {
       return methodA(input, objTest);
    }
}
return methodB(input);

我试图用

findFirst
来做到这一点,但我不知道如何称呼它

listOfObjTest.stream().filter(obj -> Objects.equals(objTest.getField(), input.getField())).findFirst().get();

您是否推荐任何有关 lambda 和流的教程,因为当我必须创建新内容时,我遇到很多问题...

java lambda java-stream refactoring
2个回答
0
投票

我推荐 O'Reilly Media 的 Java 8 Lambdas
https://www.oreilly.com/library/view/java-8-lambdas/9781449370831/

它提供了大量信息,包括您讨论的主题。


0
投票

这是与您编写的代码等效的基于流的代码:

return listOfObjTest.stream()
        .filter(objTest -> objTest.getField().equals(input.getField()))
        .findFirst()
        .map(objTest -> methodA(input, objTest))
        .orElseGet(() -> methodB(input));

这会将列表转换为流,过滤列表以仅包含与条件匹配的元素,返回第一个此类元素,然后在该元素上调用

methodA
(如果存在此类元素),或者
methodB
(如果不存在) t.

使用变量使类型明确,这与:

List<ObjTest> listOfObjTest = ...
Stream<ObjTest> stream = listOfObjTest.stream();
Stream<ObjTest> filteredSteam = 
        stream.filter(objTest -> objTest.getField().equals(input.getField()));
Optional<ObjTest> firstMatch = filteredStream.findFirst();
Optional<String> matchingField =
        firstMatch.map(objTest -> methodA(input, objTest));
String result = firstMatch.orElseGet(() -> methodB(input));
return result;

演练

以下是该方法的分步演练。

  1. 从元素列表开始。
    List<ObjTest> listOfObjTest = ...;
    
  2. 使用
    Collection.stream
    将列表转换为流。
    Stream<ObjTest> stream = listOfObjTest.stream();
    
  3. 使用
    getField
     过滤流,使其仅包含 input.getField
     值等于 
    Stream.filter(Predicate predicate)
    的元素。
    // Stream<ObjTest>
    Stream<ObjTest> filteredSteam = 
            stream.filter(objTest -> objTest.getField().equals(input.getField()));
    
  4. 使用
    Stream.findFirst
    返回包含过滤流中剩余的第一个元素的可选值,如果没有元素与过滤条件匹配,则返回空可选值。
    Optional<ObjTest> firstMatch = filteredStream.findFirst();
    
  5. 如果存在值,则使用
    methodA
     将可选值映射到 
    Optional.map(Function mapper)
    的结果。
    Optional<String> matchingField =
            firstMatch.map(objTest -> methodA(input, objTest));
    
  6. 返回匹配的字段值(如果存在),否则使用
    methodB
     返回 
    Optional.orElseGet(Supplier supplier)
    的结果。
    String result = firstMatch.orElseGet(() -> methodB(input));
    
© www.soinside.com 2019 - 2024. All rights reserved.