在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);
}
}
}
答案 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。
我个人会有两个构造函数。