首页 > 解决方案 > 在 Kotlin 中递归构建数据类

问题描述

我正在尝试创建一个递归数据类,如下所示:

data class AttributeId (
  val name: String,
  val id: Int,
  val children: List<AttributeId>?
)

我现在正在努力解决的问题是通过迭代源对象来构建数据类。我如何递归地构建这个对象?数据类在这里是错误的解决方案吗?

编辑:有关我要从中构造数据类实例的 Source 对象的更多信息

源对象是一个基本上*具有以下形状的 Java Stream:

public Category(final String value,
                      final Integer id,
                      final List<Category> children) {
    this.value = value;
    this.id = id;
    this.children = children;
}

(为简洁起见,我不关心的字段已从示例中删除)

我需要映射这个流并调用一个递归函数来构造 AttributeId 数据类,但我的尝试似乎以堆栈溢出和很多混乱结束!

标签: kotlinrecursion

解决方案


我认为包含对其他人的引用的数据类不一定有任何问题。

肯定有一些陷阱。例如:

  • 如果列表是可变的,或者它的字段是可变的(即var而不是val),那么您必须小心,因为它的哈希码 &c 可能会改变。

  • 如果链接链可以形成一个循环(即你可以跟随链接并最终回到原来的类),那可能是非常危险的。(例如,调用一个方法,例如toString()hashCode()可能陷入无限循环或使线程崩溃StackOverflowError。您必须通过覆盖这些方法以防止它们递归来防止这种情况发生。)但如果列表和字段都是不可变的。

但是,这些问题都不是特定于数据类的;一个普通的班级可能会遇到同样的问题(特别是如果你覆盖了类似toString()或不注意的方法hashCode())。因此,您是否将其设为数据类归结为它是否给人一种感觉:它的主要目的是否是保存数据,和/或自动生成的方法是否与您希望它的行为方式相匹配。

正如 Tenfour04 所说,这取决于您. 如果它自然形成一个树结构,那么这可能是一个很好的表示。

显然,你不能在它的任何孩子之前构造一个父母。(特别是,您创建的第一个实例必须具有其中一个null或一个空列表children。)这可能意味着以后序遍历源。其余的应该自然而然地脱落。


推荐阅读