2010-07-11 40 views
5

在Java中是否有一個構造函數可以接受數組或集合?我一直在擺弄這一段時間,但我認爲這是不可能的。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); 
     } 

    } 

} 

回答

19

可以申報兩個構造和第一第二個電話:

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"}); 

由於只有一個行中第一個構造函數的代碼,這是很簡約。

+0

不錯的一個。我可能會這樣做,因爲從'List '中獲取'String []'比基於'String []'構造'List '更便宜。 – BalusC 2010-07-11 01:01:21

+2

BalusC - 你錯了。 Arrays.asList(..)返回與不可變列表相同數組的視圖。幾乎沒有成本。另一方面,轉到String []需要將所有引用複製到新分配的數組中 – user44242 2010-07-11 09:26:38

+1

@usersmarvin:感謝您的支持!順便提一下,爲了通知用戶關於不屬於他們自己的問題/回答的評論,在暱稱的前面放置一個「@」,例如, '@ BalusC'。爲了找到一個匹配,至少需要名字前3個字符。 – BalusC 2010-07-14 14:54:50

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); 
    } 
} 
0

如果你真的想要一個構造函數可以使用Arrays.asList,然後有構造帶覆蓋List和Set集合。

我個人會有兩個構造函數。

1

看起來數組並不是可迭代的,所以沒有辦法做到這一點。有一個接受數組和其他迭代器的構造函數是不可能的。這是特別討厭的,因爲我們可以做到這一點:

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

看到這個職位的詳細信息:Why is an array not assignable to Iterable?

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"}); 

數組初始化的那形式只能在一個變量聲明被使用;例如

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

作爲數組創建表達式一部分;例如

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