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())
}
孩子们。收集这个。&离开列表
}
基本上将
数据
包装到列表中 代码的输出与问题要求的不同。代码的输出与问题要求的不同。