Java:一个构造函数或方法,它将接受数组或集合或列表或...?

时间:2010-07-11 00:45:00

标签: java list collections arrays constructor

在Java中,有没有一个构造函数可以接受数组或集合?我一直在摆弄这个问题,但我不认为这是可能的。

我希望能够初始化MyClass,如下所示:

MyClass c = new MyClass({"rat", "Dog", "Cat"});

就像这样:

LinkedList <String> l = new <String> LinkedList();
l.add("dog");
l.add("cat");
l.add("rat");
MyClass c = new MyClass(l);

这就是MyClass的样子。我可以做什么使XXX成为可行的?我知道我可以重载构造函数,但是如果我可以最小化那些非常棒的代码呢?

public class MyClass{

   private LinkedHashSet <String> myList;

   public MyClass(XXX <String> input){
       myList = new LinkedHashSet <String> ();
       for(String s : input){
           myList.put(s);
       }

   }

}

5 个答案:

答案 0 :(得分:20)

你可以声明两个构造函数并从第一个调用第二个:

class MyClass {
    public MyClass(String... x) {
        // for arrays
        // this constructor delegate call to the second one
        this(Arrays.asList(x));
    }
    public MyClass(List<String> x) {
        // for lists
        // all logic here
    }
}

通话看起来像

new MyClass(new ArrayList<String>());
new MyClass("dog", "cat", "rat");
new MyClass(new String[] {"rat", "Dog", "Cat"});

由于第一个构造函数中只有一行代码,因此它非常简约。

答案 1 :(得分:1)

公共类MyClass1 {

    public MyClass1(final String... animals) {
        for (final String animal : animals) {
            System.out.println("eat " + animal);
        }
    }

    public static void main(final String[] args) {
        new MyClass1();
        new MyClass1("dog", "cat", "rat");
        new MyClass1(new String[] { "dog", "cat", "rat" });
    }
}

public class MyClass2 {

    public MyClass2(final Iterable<String> animals) {
        for (final String animal : animals) {
            System.out.println("eat " + animal);
        }
    }

    public static void main(final String[] args) {
        new MyClass2(Arrays.asList("cat", "rat", "dog", "horse"));
        final LinkedList<String> animals = new LinkedList<String>();
        animals.add("dog");
        animals.add("house");
        animals.addAll(Arrays.asList("cat", "rat"));
        new MyClass2(animals);
    }
}

答案 2 :(得分:1)

看起来数组不可迭代,所以无法做到这一点。有一个接受数组和其他迭代的构造函数是不可能的。这特别令人讨厌,因为我们可以这样做:

Foo[] foos = ...
for (Foo foo : foos)

有关详情,请参阅此帖子:Why is an array not assignable to Iterable?

答案 3 :(得分:1)

理论上,您可以将构造函数声明为:

MyClass(Object args) {
    if (args instanceof List) {
        ...
    } else if (args instanceof Set) {
        ...
    } else if (args.getClass().isArray()) {
        ...
    } else {
        thrown new IllegalArgumentException("arg's type is wrong");
    }
}

但是IMO,这将是一个糟糕的API设计,因为它将所有类型检查都用于运行时。 (没有其他方法可以使用单个构造函数执行此操作。数组类型和Collection接口的唯一常见超类型是Object。)

使用构造函数重载要好得多,如其他答案中所述。

顺便提一下,以下(来自您的示例)是Java语法错误,与构造函数声明的参数类型无关:

MyClass c = new MyClass({"rat", "Dog", "Cat"});

这种形式的数组初始值设定项只能用于变量声明; e.g。

String[] foo = {"rat", "Dog", "Cat"};

作为数组创建表达式的一部分; e.g。

String[] foo = new String[]{"rat", "Dog", "Cat"};
String[][] bar = new String[][]{{"rat", "Dog", "Cat"}, /* ... */};

答案 4 :(得分:0)

如果你真的想要一个构造函数,你可以使用Arrays.asList,然后让构造函数采用一个涵盖List和Set的Collection。

我个人会有两个构造函数。