我正在尝试实现一个通用树。
每个树都有一个value
、一个parent
和一个其children
的列表。使用以下方法添加子项:
public Tree<T> addChildren(Tree<T>... children) {
for (Tree<T> child: children) {
if (this.children.add(child)) {
child.setParent(this);
}
}
return this;
}
当我有一个List
树,我想作为孩子添加时,问题就开始了:
List<Tree<T>> newChildren;
由于在Java中无法创建参数化类型的数组,因此最明显的解决方案是迭代列表并逐个添加子项:
for (Tree<T> newChild: newChildren) {
myTree.addChildren(newChild);
}
但这并不是对varargs的有效使用。既然我想让Tree
类尽可能简单,有其他方法可以实现吗?
对于一个同时接受array
和List
(或者更好的Iterable
)的方法,我最喜欢的方法是使用数组版本中的Arrays.asList()
来调用可迭代版本。示例:
public Tree<T> addChildren(Iterable<Tree<T>> children) { //for lists and collections
// same code
}
public Tree<T> addChildren(Tree<T>... children) { //for arrays and varargs
return addAll(Arrays.asList(children));
}
也不要害怕使用一些通配符,如果你想让Tree<Animal>
小时候有一个Tree<Cat>
,那么你需要把你的信号改为:
Tree<T> addAll(Iterable<? extends Tree<? extends T>> children) { ... }
Tree<T> addAll(Tree<? extends T>... children) { ... }
这可以通过创建原始类型的数组来轻松解决:
Tree<String>[] newChildrenArray = new Tree[newChildren.size()];
newChildrenArray.toArray(newChildren);
myTree.addChildren(newChildrenArray);
您可以让一个方法接受List
,并让其中一个方法调用另一个:
public Tree<T> addChildren(Iterable<Tree<T>> children) {
for (Tree<T> child : children) {
if (this.children.add(child)) {
child.setParent(this);
}
}
return this;
}
public Tree<T> addChildren(Tree<T>... children) {
return addChildren(Arrays.asList(children));
}