减少/收集"列表<映射<字符串,设置<String>"为"映射<字符串,设置<String>>"



List上执行parallelStream()后,我最终得到了一个List<Map<String, Set<String>。我想将其统一为一个Map<String, Set<String>>(它只会在 MapList中保留唯一性(。

我不熟悉collectreduce功能,所以没有什么可继续的。

现有代码:

private val TYPES = listOf("string", "integer")
private fun getLinesOfEachTypeAcrossMultipleFiles(files: List<File>): Map<String, Set<String>> {
  return files
    .parallelStream()
    .map { file ->
      TYPES.associate {
        it to getRelevantTypeLinesFromFile(file)
      }
    }
// Converted into a Stream<String, Set<String>>
// .reduce() / collect() ?
}
private fun getRelevantTypeLinesFromFile(it: File): Set<String> {
  // Sample code
  return setOf()
}

如果您正在寻找等效的 Java 代码,您可以使用 flatMap 流式传输所有条目,然后将它们收集为具有合并函数的 Map,如下所示:

Map<String, Set<String>> some(List<Map<String, Set<String>>> listOfMap) {
    return listOfMap.stream()
            .flatMap(a -> a.entrySet().stream())
            .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue,
                    (s1, s2) -> {
                        s1.addAll(s2);
                        return s1;
                    }));
}

我想出并实现了一个使用 fold 运算符(而不是 reducecollect(的 Kotlin 特定解决方案:

private val TYPES = listOf("string", "integer")
private fun getLinesOfEachTypeAcrossMultipleFiles(files: List<File>): Map<String, Set<String>> {
  return files
    .map { file ->
      TYPES.associate { it to getRelevantTypeLinesFromFile(file) }
    }
    .fold(mutableMapOf<String, MutableSet<String>>()) { acc, map ->
      acc.apply {
        map.forEach { key, value ->
          acc.getOrPut(key) { mutableSetOf() }.addAll(value)
        }
      }
    }
}
private fun getRelevantTypeLinesFromFile(it: File): Set<String> {
  // Sample code
  return setOf()
}

使用fold的好处是,我们不需要将数据的类型从Map更改为MutableMapSet更改为MutableSet

最新更新