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
接口不公开变异的方法(比如put
, putAll
)。 你可以自由地分配一个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
。