如何使用Kotlin将列表转换成地图

时间:2019-03-04 16:14:47

标签: java lambda kotlin

我正在尝试从列表中构建地图。我的目标是比较两个列表,并发现这两个列表之间的差异。然后,我想构造一个地图,以便知道我在哪个索引中发现差异。

我用Java做到了这一点,我相信这不是一种很好的方式,但是它是有效的。

//I compare the two values for a given index, if value are the same, I set null in my result list
List<String> result = IntStream.range(0, list1.size()).boxed()
                .map(i -> list1.get(i) != list2.get(i) ? (list1.get(i)  + " != "+ list2.get(i)) : null)
                .collect(Collectors.toList());

//I filter all the null values, in order to retrieve only the differences with their index
Map<Integer, String> mapResult =
            IntStream.range(0, result.size())
            .boxed().filter(i-> null != result.get(i))
            .collect(Collectors.toMap(i -> i,result::get));

这不是最佳选择,但是可以正常工作。如果您对这些代码行有建议,我会很乐意接受。

我尝试两次在Kotlin中复制这种行为,但是我没有成功使用map()构造函数。 (我仍在学习Kotlin,对此我不太熟悉。)

谢谢您的帮助。

1 个答案:

答案 0 :(得分:3)

您可以在集合中使用zip函数来连接两个元素。 withIndex()函数有助于将列表变成元素索引和值对的列表。完整的解决方案可能如下


    val list1 = listOf("a", "b", "c")
    val list2 = listOf("a", "B", "c")

    val diff : Map<Int, String> = list1.withIndex()
        .zip(list2) { (idx,a), b -> if (a != b) idx to "$a != $b" else null}
        .filterNotNull().toMap()

请注意,zip函数会在两个列表中都有元素时进行迭代,它将跳过任何列表中的剩余内容。可以通过添加具有以下功能的空元素来解决此问题:


fun <T> List<T>.addNulls(element: T, toSize: Int) : List<T> {
    val elementsToAdd = (toSize - size)
    return if (elementsToAdd > 0) {
        this + List(elementsToAdd) { element }
    } else {
        this
    }
}

并在使用zip函数之前在两个列表中调用该函数