使用通用List作为varargs参数

时间:2014-09-15 08:15:24

标签: java generics variadic-functions generic-collections

我正在尝试实现通用树。

每棵树都有一个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中的there is no way to create array of parametrized type以来,最明显的解决方案是迭代列表并逐个添加子项:

for (Tree<T> newChild: newChildren) {
   myTree.addChildren(newChild);
}

但这不是对varargs的有效使用。既然我想让Tree类尽可能简单,那还有其他方法可以实现吗?

3 个答案:

答案 0 :(得分:2)

这可以通过创建原始类型数组来轻松解决:

Tree<String>[] newChildrenArray = new Tree[newChildren.size()];
newChildrenArray.toArray(newChildren);
myTree.addChildren(newChildrenArray);

答案 1 :(得分:1)

您可以使用接受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));
}

答案 2 :(得分:1)

我最喜欢的方法是接受arrayList(甚至更好,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));
}

也不要害怕使用某些wildcards,如果你想允许Tree<Animal>生成Tree<Cat>孩子,那么你需要更改你的唱到:

Tree<T> addAll(Iterable<? extends Tree<? extends T>> children) { ... }

Tree<T> addAll(Tree<? extends T>... children) { ... }