【问题标题】:Why Extension Functions are not working on ArrayList<ArrayList<Double>>为什么扩展函数不适用于 ArrayList<ArrayList<Double>>
【发布时间】:2019-10-29 10:58:42
【问题描述】:

我对使用 Kotlin 进行 Android 开发非常陌生。我有一个由两个 Double 类型的 ArrayList 组成的 ArrayList。我想在 Big ArrayList 中的第一个元素之后丢弃/切片所有内容。在遇到 Kotlin 页面上描述的 here 属性时,我发现了一些函数,如 dropLasttake 等。但是,它们在实现时没有执行,也没有错误。我仍然得到与具有相同长度的输入相同的输出。虽然Functions 列下的addget 等功能运行良好。我肯定在这里遗漏了一些东西。实现这一目标的方法是什么?

下面是一个伪代码:-

fun padding(tokenizedinput : ArrayList<ArrayList<Double>>) : ArrayList<ArrayList<Double>> {
    var temp_storage = tokenizedinput // of size 2
    temp_storage.take(1) // OPTION 1. Only want to have first element in this ArrayList
    temp_storage.dropLast(1) // OPTION 2. Only want to drop 1 element from the end
    println("FInal size: "+ temp_storage.size) //still size 2. Why not 1!?
    return temp_storage
}

【问题讨论】:

  • 我从你的标题中删除了问号,因为ArrayList&lt;ArrayList&lt;Double&gt;&gt;? 可以是一种数据类型(表示它可以为空),这对阅读的人来说有点混乱:)
  • 谢谢,我没注意到。 :)

标签: java android kotlin arraylist


【解决方案1】:
temp_storage.take(1)

这将返回修改后的List。它不会修改您调用它的List。您忽略了返回的值。

temp_storage.dropLast(1)

同样——你忽略了函数正在做的工作。

println("FInal size: "+ temp_storage.size) //still size 2. Why not 1!?

它的大小相同,因为您没有修改它。

实现这一点的方法是什么?

如果我理解你想要什么,请使用:

fun padding(tokenizedinput : ArrayList<ArrayList<Double>>) = arrayListOf(tokenizedinput[0])

在这里,我们:

  • 获取tokenizedinput的第一个元素

  • 将其包装在 ArrayList 中,因为您需要 ArrayList&lt;ArrayList&lt;Double&gt;&gt; 响应

【讨论】:

  • 在你回答的最后,如果我理解正确的话,arrayListOf 正在创建另一个 ArrayList 来获取第一个元素值?如果是这样,我不能修改现有的ArrayListtemp_storage吗?
【解决方案2】:

List.take(n)List.dropLast(n)return 与操作一起创建一个新列表。它会不修改现有列表。尝试以这种方式记录或打印:-

println(temp_storage.take(1).size) // would be 1
println(temp_storage.dropLast(1).size) // would be 1

上面的输出将是1,如果列表的大小是2

要转换为现有列表,请使用:-

temp_storage = ArrayList(temp_storage.dropLast(1)) // need to cast it to ArrayList<T> before assigning

【讨论】:

  • 那么,我可以temp_storage = temp_storage.dropLast(1) 吗?这会修改现有列表吗?
  • @RishabhSahrawat 是的,应该
  • 如果我这样做,我会看到错误:Type inference failed. Required: ArrayList&lt;ArrayList&lt;Double&gt;&gt;. Found: List&lt;ArryList&lt;Double&gt;&gt;,当我这样做时 temp_storage = temp_storage.dropLast(1 )
  • @RishabhSahrawat 我已经编辑了答案,请检查!
  • 啊,是的,现在我明白了。从函数返回的List 必须包装到ArrayList 中。有效。谢谢你。祝你有美好的一天!
【解决方案3】:

从包含此方法的实际类中添加其他答案已经说过的内容:

采取方法:

/**
 * Returns a list containing first [n] elements.
 * 
 * @throws IllegalArgumentException if [n] is negative.
 * 
 * @sample samples.collections.Collections.Transformations.take
 */
public fun <T> Iterable<T>.take(n: Int): List<T> {
    require(n >= 0) { "Requested element count $n is less than zero." }
    if (n == 0) return emptyList()
    if (this is Collection<T>) {
        if (n >= size) return toList()
        if (n == 1) return listOf(first())
    }
    var count = 0
    val list = ArrayList<T>(n)
    for (item in this) {
        if (count++ == n)
            break
        list.add(item)
    }
    return list.optimizeReadOnlyList()
} 

还有 dropLast

/**
 * Returns a list containing all elements except last [n] elements.
 * 
 * @throws IllegalArgumentException if [n] is negative.
 * 
 * @sample samples.collections.Collections.Transformations.drop
 */
public fun <T> List<T>.dropLast(n: Int): List<T> {
    require(n >= 0) { "Requested element count $n is less than zero." }
    return take((size - n).coerceAtLeast(0))
}

可以在_Collections.kt找到

这意味着它返回一个列表,它不会修改原始集合

【讨论】:

  • 我明白了,但是如何修改ArrayList?。我应该创建另一个 ArrayList 并将所有内容保存在那里还是可以对现有的进行更改?
  • 我只是缺少结果列表的包装部分。感谢您的帮助和时间。
  • 没问题,抱歉回复延迟我没有看到你的评论,你可以把结果分配给另一个数组列表,你可能已经知道了:)
猜你喜欢
  • 1970-01-01
  • 2012-06-25
  • 1970-01-01
  • 2013-09-10
  • 2016-05-14
  • 1970-01-01
  • 2018-10-03
  • 2021-01-05
  • 1970-01-01
相关资源
最近更新 更多