当前位置: 首页 > 知识库问答 >
问题:

科特林,从链接列表中删除重复项:智能投射是不可能的

闾丘成礼
2023-03-14

我在kotlin中实现了一个LinkedList,并编写了一个方法从中删除重复项:

class Node (value:Int) {
    var value = value
    var next:Node? = null

fun addNodeToTail(value:Int){
    var node = this
    while (node.next != null) {
        node = node.next
    }
    val newNode= Node(value)
    node.next= newNode

}
fun removeDuplicates (){

    val set = HashSet<Int>()
    var node = this
    set.add(node.value)
    while(node.next != null){
        if (set.contains(node.next?.value)){
            node.next= node.next?.next
        }else{
            set.add(node.next.value)
            node= node.next
        }
    }
}
}

在最后两行:

 set.add(node.next.value)
 node= node.next

(在addNodeToTail方法中),编译器表示由于复杂的表达式,智能转换是不可能的。我必须添加非空断言调用(!!)。

我想了解为什么这个解决方案不被接受,尽管while表达式检查该节点。next不为空。我想知道是否有比使用非空断言调用更好的解决方案(!!)。

感谢您的帮助

共有1个答案

关玮
2023-03-14

帕维尔在评论中严格地回答了这个问题。

基本上,智能铸造并不总是可能的。特别是,如果您定义了一个可空类型的可变<code>var</code>且在技术上可由多个线程访问,则html" target="_blank">编译器无法保证该值在空检查和使用之间保持不变。这就是为什么你会得到这个错误“智能铸造不可能”。

处理该问题的一种常见方法是将该值存储在本地val变量中,以确保该值不会更改,并允许编译器对其进行智能强制转换。

但是在您的情况下,这并不理想,因为< code>while每次都必须检查实际节点的值。因此,您必须在某个时候断言该值不为null,或者用< code >!!还是用猫王(< code >?:)和一个< code>error()或< code>throw。

我个人会选择:

    while (node.next != null) {
        val nextNode = node.next ?: throw ConcurrentModificationException()
        if (set.contains(nextNode.value)) {
            node.next = nextNode.next
        } else {
            set.add(nextNode.value)
            node = nextNode
        }
    }
 类似资料:
  • 问题内容: 我想从排序的链表{0 1 2 2 3 3 4 5}中删除重复项。 ` ` prev.setNext(tempHeader)在while循环内无法正常工作。理想情况下,当prev = 2且tempHeader = 3时,prev.next应该是data = 3的节点。 Printlist函数仅使用标题指针并打印列表。 节点定义如下。 问题答案: 循环已排序,因此您知道重复项将彼此相邻。如

  • 我已经实现了一个函数,我过去常常传递给anko的应用程序递归。 在这个函数里面,我想添加一个边际结束是视图在一个LinearLayout里面,所以我写了下面的代码: 我收到错误,即视图.布局参数是一个可变属性,可以更改。所以我不得不强迫演员: 在这里看堆栈溢出,我看到 Kotlin 不会在可为空的变量中智能强制转换,但 view.layoutParams 不能为空,那么为什么智能强制转换无法推断出

  • 问题内容: 我在Python中有一个列表列表: 我想从中删除重复的元素。如果这是正常列表,而不是我可以使用的列表set。但不幸的是,该列表不可散列,因此无法建立一组列表。只有元组。因此,我可以将所有列表转换为元组,然后使用set并返回列表。但这不是很快。 如何以最有效的方式做到这一点? 上面的结果应为: 我不在乎保留订单。 注意:这个问题很相似,但不是我所需要的。搜索了SO,但没有找到确切的重复项

  • 我下面有一个类,想删除包含同名的重复人,如何使用Java8 Lambda,预计列表包含下面的p1、p3。

  • 我有这个代码: 其中是类型的参数 < code>var mMeshes: MutableList 编译器在最后一行抱怨,我试图在那里声明 智能投射到

  • 结果:[1,2,3,3,3,4,4][1,2,3,3,3,4,4]