【问题标题】:Java 8 Lambda To Handle for > if > elseJava 8 Lambda 处理 > if > else
【发布时间】:2016-03-31 18:04:39
【问题描述】:

我需要根据一大堆过滤器运行两个不同的任务

我刚刚掌握了 Lambda 的概念,所以我想我的问题是,您如何在 Lambda 中处理包含复杂逻辑的多个“else”条件?

我知道我可以使用过滤器和映射来选择某些数据。 “嵌套”如何与过滤器一起使用?

我可以这样做吗:

//Iterate over list of sites
sites.stream()
//Check if current site is active
.map(isActive ? 
//{Do something with site because site is active};
//Set a variable for later user maybe?
:
//{Do something else involving the current site because it's not?};
//Set a different variable maybe?
);

//use variable from first map?

当我运行这些让我很困惑的抽象过程时,有人可以为我提供一些正确的语法,或许还可以对我正在对我的数据做什么的基本解释。

其次,如果我想并行运行这两个地图进程,我会这样做吗?

sites.stream().parallel()?

像往常一样,感谢您帮助我的无知!

【问题讨论】:

  • 我认为你最好坚持使用传统编程来完成这些类型的任务。
  • 所以我很清楚......如果我有两个简单的程序路径,如果为真,则执行任务 1,如果为假,则执行任务 2,lambdas 不是真正的方法吗?跨度>
  • 也许你应该在你的站点对象中加入更多的逻辑,让他们决定做什么,见Tell-Don't-Ask principle。这样你就可以简单地从外部调用sites.forEach(Site::doSomething) 并将逻辑放在Site 类中。

标签: java if-statement lambda parallel-processing java-8


【解决方案1】:

lambda 用法的一些例子:

您可以按活动和非活动对站点进行分组,之后您可以对两者执行一些逻辑。把大逻辑放到一个方法中,然后调用map()函数。

您也可以使用filter() 来获取流的一部分。

public class Lambda {

    static class Site {

        public boolean isActive;
        public boolean otherCondition;
        public boolean isActive() {
            return isActive;
        }

        public boolean isOtherCondition() {
            return otherCondition;
        }

        public void setProperty(String property) {

        }
    }
    public static Site someOperation(Site site) {

        //some code

        return site;
    }
    public static void main(String[] args) {

        ArrayList<Site> sites = new ArrayList<>();

        Map<Boolean, List<Site>> groupedSites = sites.stream().collect(Collectors.groupingBy(Site::isActive));          
        groupedSites.get(Boolean.TRUE).stream().filter(Site::isOtherCondition).map(Lambda::someOperation).forEach(p -> p.setProperty("something"));

    }
}

【讨论】:

  • 谢谢!这很有帮助!我现在可以利用多个处理器同时处理多个列表,并且代码的复杂性要低得多。可能更令人困惑,但总体上不那么复杂!
  • 您可以将Collectors.groupingBy(Site::isActive) 替换为Collectors.partitioningBy(Site::isActive)。然后你会得到一个优化的映射,将true和false精确映射到一个值,如果没有匹配,它将有一个空列表,所以后续groupedSites.get(Boolean.TRUE).stream()不会抛出NullPointerException那个案子。另外,请注意有一个重载接受下游收集器在收集时正确执行操作,而不是将所有内容存储到列表中并在之后执行流操作。
  • @Holger 哦,谢谢,我不知道那个方法,有用的评论。
【解决方案2】:

我会将复杂的逻辑放到一个单独的方法中,并在map(…) 中引用它。

sites.stream()
    .map(Foo::bar)
    …;

这将使用类 Foo 中的一个方法,如下所示:

public static String bar(Site site)
{
    return site.toString();
}

当然你可以在方法中使用任意逻辑,但它应该没有副作用。

是的,如果用于映射的方法是线程安全的,您可以使用parallel() 并行运行映射。

【讨论】:

    【解决方案3】:

    您只需使用简单的if:

    .map(site -> {
       if (isActive) {
         ...whatever...
       } else {
         ...whatever else...
       }
     })
     ...
    

    【讨论】:

    • @TheFunk 没有。 Lambda 和流并不总是最好的解决方案。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-09-26
    • 2017-07-15
    • 1970-01-01
    • 1970-01-01
    • 2023-02-09
    相关资源
    最近更新 更多