java - 递归返回集合或集合中的元素

标签 java recursion groovy closures static-typing

这是一个简单的递归算法,用于从树的叶子生成嵌套列表:

/** Make a list from bottom level of equal path tree - list would be nested according
    to hierarchy in tree.

     1
    /  \
   2    3
   /\   |
  4  5  6
    ==>
    [[4, 5], 6]
 */
List leavesToList(TreeNode node) {
    List<TreeNode> children = node.getChildren()
    if (!children) {
        return node.getData() // Problem with static typing!!
    }
    if (children.size() == 1) {
        return leavesToList(children[0])
    }
    return children.collect {leavesToList(it)}
}

该算法适用于动态类型,但静态类型会导致非列表问题 函数无法返回值。对于这种情况,理想情况下返回值 类型为 Collection<T>|T但这样的类型规范是不可能的。

作为一种解决方案,我想到了一个像这样的包装器解决方案:

@CompileStatic
static List leavesToList(Tnode rnode) {
    Closure inner
    inner = { Tnode node ->
        List<Tnode> children = node.getChildren()
        if (!children) {
            return node.getData()
        }
        if (children.size() == 1) {
            return inner.call(children[0])
        }
        return children.collect { inner.call(it) }
    }
    return inner.call(rnode) as List
}

问题:

  • 包装器实现的效率是否比原始实现低? 例如,设置闭包是否有重复开销?

  • 作为一种通用技术(而不是特定于示例案例的技巧),有吗 除了使用包装器之外,还有更好的方法来处理这种情况吗?

最佳答案

我希望我没有在这里遗漏一些东西,但为了静态类型,我会做这样的事情:

@CompileStatic
List leavesToList(TreeNode node) {
   List<TreeNode> children = node.children
   if (!children) {
      return [node.data]
   }
   if (children.size() == 1) {
      return leavesToList(children.first())
   }
   children.collect this.&leavesToList
}

基本上将数据包装到一个列表中。

关于java - 递归返回集合或集合中的元素,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35423313/

相关文章:

scala - 分数和的尾递归函数

c - C中打印Trie的内容和数量

android - 在 android studio 的 build.gradle 中使用 flavor 维度

Mac OS High Sierra 上的 Java 驱动程序 Firebird 2.5

java - Java中的多线程错误

python - 如何有效地在django中递归查询?

groovy - 将 PowerMock 与 Spock 结合使用

java - 错误java.lang.NoSuchMethodError : No such DSL method '***' found among steps

java - 动态添加组件到 JScrollPane

java - 尝试停止线程并在后台停止 ffmpeg