可以使用功能操作

2022-09-01 23:35:01

我在Java中使用for-each结构,如下所示:

public int getNumRStations() {
    int numRoutes = 0;

    for (ArrayList<Route> route : routes) {
        numRoutes += route.size();
    }

    return numRoutes;
}

NetBeans 显示一个警告/通知,指出“可以使用功能操作”。自动解析后,新生成的代码将显示以下内容:

public int getNumRStations() {
    int numRoutes = 0;

    numRoutes = routes.stream().map((route) -> route.size()).reduce(numRoutes, Integer::sum);

    return numRoutes;
}
  1. 为什么 NetBeans 会警告我这一点?我知道我不应该盲目地信任IDE,所以这就是为什么我要问。
  2. 那条新线应该做什么?我没有见过这样的东西,无论是在现实生活中还是在课堂上。

答案 1

这看起来像是 NetBeans 建议将 sum 操作重构为 Java 8 “lambda”或函数式编程操作,使用 Stream 接口中的映射和 reduce 函数。您必须将 Java 8 JDK 与 NetBeans 配合使用。

分解它正在做的事情:

  • “map()”函数正在对数组列表中的所有大小进行计数,routeroutes

  • 然后,“reduce()”函数执行这些单个大小的总和,以获得路由总数的最终结果。

map() 和 reduce() 函数记录在此链接中提供的 Stream 接口的 Java 8 文档中

这个答案解决了“它是什么”,但没有解决“为什么它更好”。我承认自己仍然在学习这些结构。


答案 2

因此,@paisanco已经解释了每个函数的作用。

我同意IDE建议的修改比原始修改更复杂。
如果要求我在原始版本和IDE推荐之间进行选择,那么我将选择原始版本。

但是,对于您的示例,这里有一种更简单(也是更首选)的方法。

public int getNumRStations() {
    return routes.stream().mapToInt(x -> x.size()).sum();
}

在这种情况下,解释也更简单。
对于每个路由的元素,将其更改为并将它们求和。xx.size()

x -> x.size()称为 lambda 表达式或匿名函数。就像

int function(x) {
    return x.size();
}

(我省略了参数类型。该类型由 Java 编译器隐式选择。
此函数应用于集合的每个元素。这就是方法的作用。mapToInt(lambda exp)

sum()方法似乎不需要解释。

很简单,不是吗?