Kotlin / Java在地图中收集地图的功能和不可变的方式

目前,我正在通过Java API读取文件,并通过foreach方法将项目添加到地图,这迫使我使用mutablemap。 有没有收集项目没有mutablemap的方式? 我知道有一个方法收集,但我无法得到它的工作。

目前的方式:

val result = mutableMapOf<Int, MutableMap<Int, Double>>() Files.lines(Paths.get(folderPath)) .map { line -> line.split(",") } .map { items -> Triple(items[0].toInt(), items[1].toInt(), items[2].toDouble()) } .forEach { (id, article, rating) -> if (result.containsKey(id)) result[id]!!.put(article, rating) else result.put(id, mutableMapOf(Pair(article, rating))) } 

编辑:

我的目标是基于三元组的第一个值合并三元对象。 所以情景会是两个三重对象(1,2,5.5)和(1,3,5.5)。 三元组的第一个值是用户ID,第二个是文章ID,第三个是文章的评分。 在合并之后,在地图上将会有一个单独的条目,其中包含第一个键=用户ID,三元组的第一个值,并且该值将是包含用户评分的文章的地图。

目前我正在努力工作,但是我很好奇是否有解决这个问题的更有效的方法。

你可以这样做:

 val result: Map<Int, Map<Int, Double>> = Files.lines(Paths.get(folderPath)) .map { it.split(",") } .collect(groupingBy({ it[0].toInt() }, toMap<List<String>, Int, Double>({ it[1].toInt() }) { it[2].toDouble() })) 

编译器似乎不能推断toMap的类型,所以我在那里添加了一个类型提示。

我将指出,Kotlin没有一个不可变的Map实现。 mapOf返回的默认值可变的java.util.LinkedhashMap 。 只是Map接口不公开变异的方法(比如putputAll )。 你可以自由地分配一个MutableMap<Int, MutableMap<Int, Double>>到一个Map<Int, Map<Int, Double>> ,这也是我在这里用result的类型注解所做的,迫使静态类型成为不可变的Map

我对Kotlin不够舒服,但似乎应该使用一个简单的: Collectors.collectingAndThen 。 就像是:

  System.out.println(Stream.of(1, 2, 3, 1) .collect(Collectors.collectingAndThen( Collectors.groupingBy(Function.identity(), Collectors.counting()), Collections::unmodifiableMap))); 

这个想法是,你收集到一个可变的地图,然后将其包裹到ImmutableMap。

如果顺便说一句,你在课堂上有guava – 它建立收集器收集到ImmutableMap