gpt4 book ai didi

kotlin - 如何在不可变的Kotlin类中创建父子关系

转载 作者:行者123 更新时间:2023-12-02 13:08:52 24 4
gpt4 key购买 nike

我有代表一棵树的不可变类,其中子代需要父代引用。

sealed class Node {
abstract val parent: Parent?
}

class Child(
override val parent: Parent,
) : Node()

class Parent(
override val parent: Parent?,
val children: List<Node>
) : Node()

Kotlin是否有一种惯用的方式来创建带有正确设置了父级引用的子级列表的父级?

最佳答案

您可以尝试使用根节点和构建器参数:

sealed class Node {
data class Root(
val createChildren: ParentList.() -> Unit
) : Node() {
val children: List<Node> = ParentList(this).apply(createChildren)
}

data class Branch(
val createChildren: ParentList.() -> Unit,
val parent: Node
) : Node() {
val children: List<Node> = ParentList(this).apply(createChildren)
}

data class Leaf(
val parent: Node
) : Node()
}

class ParentList(
val parent: Node,
private val children: MutableList<Node> = mutableListOf()
) : List<Node> by children {

fun branch(createChildren: ParentList.() -> Unit) {
children += Node.Branch(createChildren, parent)
}

fun leaf() {
children += Node.Leaf(parent)
}

}

fun root(createChildren: ParentList.() -> Unit) = Node.Root(createChildren)

可以按照以下方式构造它们(可能要向两个节点中的任何一个添加额外的详细信息):
fun usage() {

val graph = root {
branch {
leaf()
}
branch {
branch {
leaf()
}
leaf()
}
}
}

您可以通过扩展属性允许访问潜在的 child 和/或 parent :
val Node.children: List<Node> get() = when(this) {
is Node.Root -> children
is Node.Branch -> children
is Node.Leaf -> emptyList()
}

val Node.parent: Node? get() = when(this) {
is Node.Root -> null
is Node.Branch -> parent
is Node.Leaf -> parent
}

因此,您可以导航后代:
fun Node.allChildren(): List<Node> = 
children + children.flatMap { it.allChildren() }

或向上导航:
fun Node.allParents(): List<Node> = 
listOfNotNull(parent).flatMap { listOf(it) + allParents() }

为了避免评估可能会提前完成的搜索,您始终可以使用序列而不是列表:
fun Node.allChildren(): Sequence<Node> = 
children.asSequence() + children.asSequence().flatMap { it.allChildren() }

fun Node.allParents(): Sequence<Node> =
listOfNotNull(parent).asSequence().flatMap { sequenceOf(it) + it.allParents() }

注意:当心Stackoverflows

关于kotlin - 如何在不可变的Kotlin类中创建父子关系,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53130288/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com