目前,我被告知要对在某些服务器上挂出的所有.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)吗?
答案 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();