如何将这种排序的映射方法从Java转换为Kotlin

时间:2018-06-21 09:15:27

标签: java kotlin

如何将以下Java转换为Kotlin?

private Map<String, Map<String, String>> example(List<Dto> dtos) {

    if (dtos.isEmpty()) {
        return ImmutableMap.of();
    }

    final Map<String, Map<String, String>> outerMapByField1 = new TreeMap<>();

    dtos.forEach(dto -> {

        final String field1 = dto.getField1();

        final Map<String, String> innerMapByField2 = outerMapByField1.computeIfAbsent(field1, (key) -> new TreeMap<>());
        innerMapByField2.put(dto.getField2(), dto.getField3());

    });

    return outerMapByField1;

}

IntelliJ转换使我可以使用某些东西,而我对其进行重构的尝试却以以下内容结束,该内容无法编译。

private fun example(dtos: List<Dto>): Map<String, Map<String, String>> {

    if (dtos.isEmpty()) {
        return ImmutableMap.of()
    }

    val outerMapByField1 = sortedMapOf<String, Map<String, String>>()

    dtos.forEach { dto ->

        val field1 = dto.field1

        val innerMapByField2 = outerMapByField1.getOrPut(field1) { key -> TreeMap() }
        innerMapByField2.put(dto.field2, dto.field3)

    }

    return outerMapByField1

}

2 个答案:

答案 0 :(得分:2)

默认情况下,Kotlin中的地图是不可变的,因此添加一些可变性将使其可编译:

 private fun example(dtos: List<Dto>): Map<String, Map<String, String>> {

        if (dtos.isEmpty()) {
            return emptyMap()
        }

        val outerMapByField1 = sortedMapOf<String, MutableMap<String, String>>()

        dtos.forEach { dto ->

            val field1 = dto.field1

            val innerMapByField2 = outerMapByField1.getOrPut(field1) { mutableMapOf() }
            innerMapByField2.put(dto.field2, dto.field3)

        }

        return outerMapByField1

    }

也许是这样的:

private fun example(dtos: List<Dto>) = dtos.groupBy { it.field1 }.map { entry ->
    entry.key to entry.value.associateBy { it.field2 }.mapValues { it.value.field3 }.toSortedMap()
}.toMap().toSortedMap()

答案 1 :(得分:2)

  • 首先,您的outerMapByField1中的值是Map实例,它是一个只读接口。要修改这些地图,您需要将它们存储为MutableMap(根据@Heinrisch的回答)。
  • Kotlin提供了一个emptyMap()功能,您可以考虑使用它代替ImmutableMap.of()
  • 传递给getOrPut的lamda不带参数,因此您必须删除key ->

所有这些都适用:

private fun example(dtos: List<Dto>): Map<String, Map<String, String>> {

    if (dtos.isEmpty()) {
        return emptyMap()
    }

    val outerMapByField1 = sortedMapOf<String, MutableMap<String, String>>()

    dtos.forEach { dto ->

        val field1 = dto.field1

        val innerMapByField2 = outerMapByField1.getOrPut(field1) { TreeMap() }
        innerMapByField2.put(dto.field2, dto.field3)

    }

    return outerMapByField1

}