将List <map <string,set <string =“”>`减少/收集为Map <string,set <string =“” >>`

时间:2019-04-05 02:19:22

标签: kotlin java-stream reduce collect

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

我不熟悉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()
}

2 个答案:

答案 0 :(得分:1)

如果您正在寻找等效的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;
                    }));
}

答案 1 :(得分:0)

我弄清楚并实现了一个使用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更改为MutableMap,而将数据类型从Set更改为MutableSet