重构使用流API的方法

时间:2019-03-26 11:44:42

标签: java java-8 sum java-stream

目前,我被告知要对在某些服务器上挂出的所有.sql文件进行计数。手动解决这个非常 basic 的任务不是一个选择,相反,我编写了一些使用SimpleFileVisitor<Path>的代码,并将找到的所有sql文件及其父路径存储在{{ 1}}。

现在,我想接收独立于其位置发现的sql文件总数。我使用增强的Map<Path, List<Path>>循环(几乎是经典方式)来工作:

for

现在的问题是,如何使用流API进行相同的操作?

我无法使可编译代码正常工作,但这显然并没有做错事。
不幸的是,以下行对我来说似乎是一个一个好主意,但对编译器而言,这不是。

public int getTotalAmountOfSqlFiles(Map<Path, List<Path>> sqlFilesInDirectories) {
    int totalAmount = 0;

    for (Path directory : sqlFilesInDirectories.keySet()) {
        List<Path> sqlFiles = sqlFilesInDirectories.get(directory);
        totalAmount += sqlFiles.size();
    }

    return totalAmount;
}

编译器说

  

无法推断totalAmount = sqlFilesInDirectories.entrySet().stream().map(List::size).sum(); 的类型参数

有人知道我在做什么错(也许使用解决方案提供一些有教养的流API)吗?

4 个答案:

答案 0 :(得分:12)

当所需的总和仅包含值中的列表大小时,不确定在这里人们为什么涉及keySet。只需将所有值的大小相加即可。

return sqlFilesInDirectories.values().stream().mapToInt(List::size).sum();

甚至for循环版本也应该就是这个

for (List<Path> list : sqlFilesInDirectories.values()) {
    totalAmount += list.size();
}

实际上并不需要遍历键集,然后从map中获取价值,并且也不是更好的性能。

答案 1 :(得分:4)

这是因为在流中您正在使用整个条目而不是值。应该这样做:

//define firebase login
#define FIREBASE_HOST "someDatabase.someGoogleLink.com"
#define FIREBASE_AUTH "someSecret"

//db path
#define DB_PATH "/control/"

#define BASKING_TIME "/control/baskingTime"
#define IR_STATUS "/control/irStatus"
#define UV_STATUS "/control/uvStatus"
#define START_MINUTE "/control/startMinute"
#define START_HOUR "/control/startHour"
#define OVERRIDE "/control/overRide"
#define TEMPERATURE "/temperature"
#define HUMIDITY "/humidity"

答案 2 :(得分:3)

其他答案是汇总所有条目的最短方法,但是如果您需要每个Path的脚本数量,则可以使用以下方法:

Map<Path, Integer> amountOfFilesForPath =
        files.entrySet().stream().collect(Collectors.groupingBy(Map.Entry::getKey,
        Collectors.summingInt(value -> value.getValue().size())));

您还可以获得总价值:

int sum = amountOfFilesForPath.values().stream().mapToInt(Integer::intValue).sum();

答案 3 :(得分:1)

尝试

int totalAmount = sqlFilesInDirectories.keySet().stream().map(sqlFilesInDirectories::get).mapToInt(List::size).sum();