【问题标题】:Java Stream forEach Loop with Multiple Conditions具有多个条件的 Java Stream forEach 循环
【发布时间】:2021-05-21 04:32:33
【问题描述】:

我有一个 forEach 循环,对于性能问题,我被告知使用 Java 流而不是这个。我有多个案例,我的代码如下所示。我找不到任何包含多个案例的流示例。谁能帮我转换一下?提前非常感谢。

name = "Serena";
for(Integer age : ages){
   if(age>10 && age<20)
        methodA(name);
   else if(age>20 && age<30)
        methodB(name);
   else
        methodC(name);

【问题讨论】:

    标签: java for-loop foreach java-stream


    【解决方案1】:

    对于更新后的问题,Stream API 可用于将年龄映射到 Consumer&lt;String&gt;,使用对方法 methodA, methodB, methodC 的引用,然后调用 Consumer::accept,但这似乎不是很有用,可以视为只是一个练习:

    public static void main(String .... args) {
        List<Integer> ages = Arrays.asList(1, 10, 15, 20, 22, 30, 33);
    
        ages.stream()
            .map(MyClass::byAge)
            .forEach(action -> action.accept("Serena"));
    }
    
    // mapper to specific method
    static Consumer<String> byAge(int age) {
        return 10 < age && age < 20
                ? MyClass::methodA
                : 20 < age && age < 30
                ? MyClass::methodB
                : MyClass::methodC;
    }
    
    // consumer methods
    public static void methodA(String name) {
        System.out.println("A: " + name);
    }
    
    public static void methodB(String name) {
        System.out.println("B: " + name);
    }
    
    public static void methodC(String name) {
        System.out.println("C: " + name);
    }
    

    【讨论】:

    • 我们可以在byAge 方法中使用“switch”作为表达吗? (跟不上最新最好的 Java :))
    • @Gavin,switch 语句是否支持某些较新版本的 Java 中的范围? Afaik,case 只允许使用常量值。此示例中的范围可以替换为 return switch (age) { case 11, 12, 13,...19 -&gt; MyClass:methodA; case 21, 22, 23,... 29 -&gt; MyClass:methodB; default -&gt; MyClass:methodC;}
    • 感谢您的澄清。我想我对所有预览功能和建议都搞混了 :)
    【解决方案2】:
    List<Integer> ints = Arrays.asList(11, 22, 30, 40);
    
    ints.forEach(i -> {
            if (i> 10 && i < 20) {
                System.out.println("Value between 10 & 20");
            } else if(i >= 20 && i < 30) {
                System.out.println("Value between 20 & 30");
            } else if(i>=30 && i <40) {
                System.out.println("Value between 30 & 40");
            }
        });
    

    【讨论】:

    • 感谢您的回答。我将此应用于我的代码,但我更新了问题,因为我无法将参数传递给方法。你能帮我解决这个问题吗?谢谢。
    • 使name 最终确定。对于使用捕获变量的 lambda,它最实际上是 final。
    • 谢谢。我应该检查列表以查看它是否为空还是流自动检查它?
    • @Serena 您的方法将 methodA、methodB、methodC 标记为静态,如果您将代码调用到您的 main 方法中,看看是否有效。
    • 使用forEach时不需要stream()
    【解决方案3】:

    您可以将 forEach 与您的代码一起使用。不确定这是您想要的还是为什么。

    ages.forEach(age -> {
        if(age > 10 && age < 20) {
            methodA(age);
        }
        else if(age > 20 && age < 30) {
            methodB(age);
        }
        else {
            methodC(age);
        }
    });
    

    【讨论】:

    • 使用forEach时不需要stream()
    • 是的,但问题是如何使用流:-)
    • 另外,如果年龄是一个数组,你将不得不使用 IntStream.of(ages)
    • 我一直认为List.forEach 是一个流,因为我认为它只是List.stream.forEach 的快捷方式
    • 你可能是对的。不过真的没关系。我会选择较短的版本,所以我更新了我的答案。虽然我通常更喜欢使用 stream().map() 来区分方法 A、B 和 C,但让它们返回一些内容,然后处理该结果。但这并不是真正的问题。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-08-07
    • 1970-01-01
    • 2013-06-30
    • 2021-12-28
    • 1970-01-01
    • 2023-01-29
    • 1970-01-01
    相关资源
    最近更新 更多