Java 递归返回集合或集合中的元素

Java 递归返回集合或集合中的元素,java,recursion,groovy,closures,static-typing,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)

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

/** 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)}
}
/**从等距路径树的底部创建一个列表-列表将根据
在树中创建层次结构。
1.
/  \
2    3
/\   |
4  5  6
==>
[[4, 5], 6]
*/
列表叶列表(树节点){
List children=node.getChildren()
如果(!儿童){
return node.getData()//静态类型有问题!!
}
if(children.size()==1){
返回离开列表(子项[0])
}
返回children.collect{leavesToList(it)}
}
该算法适用于动态类型,但静态类型会导致非列表问题 函数无法返回值。理想情况下,在这种情况下,返回值 将属于
集合| 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
静态列表leavesToList(Tnode rnode){
闭合内部
内部={t节点->
List children=node.getChildren()
如果(!儿童){
return node.getData()
}
if(children.size()==1){
返回内部调用(子项[0])
}
返回children.collect{inner.call(it)}
}
将内部调用(rnode)作为列表返回
}
问题:

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

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


    • 我希望这里没有遗漏什么,但为了静态键入,我会这样做:

      @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
      }
      
      @CompileStatic
      列表叶列表(树节点){
      List children=node.children
      如果(!儿童){
      返回[node.data]
      }
      if(children.size()==1){
      返回leavesToList(children.first())
      }
      孩子们。收集这个。&离开列表
      }
      

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

      我希望这里没有遗漏什么,但为了静态键入,我会这样做:

      @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
      }
      
      @CompileStatic
      列表叶列表(树节点){
      List children=node.children
      如果(!儿童){
      返回[node.data]
      }
      if(children.size()==1){
      返回leavesToList(children.first())
      }
      孩子们。收集这个。&离开列表
      }
      

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

      代码的输出与问题要求的不同。代码的输出与问题要求的不同。