代码之家  ›  专栏  ›  技术社区  ›  HelloCW

为什么在Kotlin中启动Flatmap时需要调用tolist()?

  •  3
  • HelloCW  · 技术社区  · 6 年前

    我用的时候能得到正确的结果 my.flatMap {it.toList()} .

    我认为VAL my 是一个 List<String> ,所以我不需要调用 toList() 但是代码 var ok3=my.flatMap { it } 无法编译,为什么?

    更重要的是,代码 var ok2=my.flatMap { bb } 得到一个错误结果,为什么?

    代码A

    var my=listOf("abc","cef")
    var bb=my.toList()
    
    var ok1=my.flatMap {it.toList()}
    var ok2=my.flatMap { bb }
    //var ok3=my.flatMap { it }  //It's wrong
    

    结果

    enter image description here

    至Naetmul:

    谢谢!

    你为什么这么认为 it String 键入代码 val ok3=my.flatMap { it }

    在我看来, 应该是 我的 键入lambda表达式,然后 我的 列表<字符串> 类型。

    图像 enter image description here

    2 回复  |  直到 6 年前
        1
  •  3
  •   Naetmul    6 年前

    旁注:如果你不重新分配, val var .


    val my = listOf("abc","cef")
    val bb = my.toList()
    

    这里是 my List<String> ,其元素是 "abc" "cef" .

    的类型 bb 列表<字符串> 因为 List 转化为 ,
    它的元素是 “ABC” “CEF” .

    即。, 我的 BB 是等效的,尽管它们是不同的实例。你不需要 BB .


    var ok1 = my.flatMap {it.toList()}
    

    这和

    var ok1 = listOf<Char>() // empty List
    for (it in my) {
        // `it` is the `String` type.
        // For the 1st iteration, it = "abc"
        // For the 2nd iteration, it = "cef"
    
        val chars: List<Char> = it.toList() // String is transformed into List of Chars
    
        ok1 = ok1 + chars
    }
    

    var ok2 = my.flatMap { bb }
    

    这和

    var ok2 = listOf<String>() // empty List
    for (it in my) {
        // `it` is the `String` type.
        // For the 1st iteration, it = "abc"
        // For the 2nd iteration, it = "cef"
    
        ok2 = ok1 + bb // You know, bb = listOf("abc, "cef")
    }
    

    所以, ok2 = bb + bb (for循环重复两次,因为 我的 有2个元素。)
    这意味着 ok2 = listOf("abc", "cef") + listOf("abc", "cef")
    这意味着 ok2 = listOf("abc", "cef", "abc", "cef")


    val ok3=my.flatMap { it }  //It's wrong
    

    这和

    var ok3 = listOf<?>() // empty List
    for (it in my) {
        // `it` is the `String` type.
        // For the 1st iteration, it = "abc"
        // For the 2nd iteration, it = "cef"
    
        ok3 = ok3 + it
    }
    

    ok3 一定是 类型。然而, it String 类型,类型不匹配。 所以,编译错误!


    如果需要连接 属于 ,您可以使用 joinToString() 方法。
    val my = listOf("abc", "cef")
    val concat = my.joinToString("") // insert empty string between elements.
    

    请参阅 Kotlin standard library document of List .

    fun <T, R> Iterable<T>.flatMap(
        transform: (T) -> Iterable<R>
    ): List<R>
    

    返回从以下结果生成的所有元素的单个列表: 正在对原始元素的每个元素调用转换函数 收藏。

    假设一个变量 list 具有类型 List<T> .

    如果我们想执行 val newList = list.flatMap(function) 然后

    function 应具有函数类型 (T) -> Iterable<R> .
    ( 功能 的参数是 T -类型,然后重新运行 Iterable<R> . 是的子类型 Collection Collection is a subtype of 可迭代的 , so is a subtype of 不可复制`.)

    newList 将具有类型 List<R> .

    问题中的参数将是 功能 .

    所以, T -类型,不是 列表<t> -类型。
    即。, -类型,不是 列表<字符串> -类型。

        2
  •  1
  •   aids61517    6 年前

    1。

    var my=listOf("abc","cef")
    var ok1=my.flatMap {it.toList()}
    //var ok3=my.flatMap { it }  //It's wrong
    

    在这种情况下:
    - flatMap 转换 A Iterable<>
    -类型 it String .
    - String.toList() 退货 List<Char>

    var ok3=my.flatMap { it } 是错误的,因为你需要改变 Iterable<gt; 喜欢 List<>

    2。

    var ok2=my.flatMap { bb } get an error result
    

    my 有两个元素,所以 my.flatMap { bb } 回程做两次 bb .
    你会得到 {"abc","cef","abc","cef"} 返回两次后 BB