2012-12-10 28 views
8

我想寫一個函數,需要一些字符串,並與他們做一些事情。讓一個Java函數接受一個集合或一個數組

我要做的唯一事情就是這組字符串循環着它們。現在我結束了沿着

public void foo(String[] myStrings){ 
    foo(java.util.Arrays.asList(myStrings)); 
} 

public void foo(Iterable<String> myStrings){ 
    for(String i : myStrings){ 
     bar(i); 
    } 
} 

線尷尬構建體感覺多餘的,因爲

for(String i : myStrings){ 
    bar(i); 
} 

將是字符串型]的myStrings完全有效的代碼。

是否有一個我可以讓foo接受的類將允許集合和數組?

回答

8

Why is an array not assignable to Iterable?

簡短的回答:沒有。根據我的理解,數組類型是合成代碼,因此不會實現Iterable或任何其他類型。您需要提供重載方法或要求客戶在呼叫站點撥打Arrays.asList

+1

謝謝,我想我仍然試圖說服它的內心深處它是Python的Java。 – BostonJohn

+1

哈哈,這裏沒有打字的鴨子 - 對不起。 :) –

+1

歡迎來到詳細輸入的世界。 Java的基礎是WET而不是DRY的原則(如在寫一切而不是不重複自己)。 – akuhn

3

不幸的是,儘管for-each循環在兩者上都工作,但數組並不實現Iterable

你完全可以只接受Iterable,因爲傳遞數組有點老派(數組在ArrayList的性能好處可以忽略不計)。使用Arrays.asList(T... a)可以輕鬆地將現有陣列包裝並轉換爲List

+0

這是一個很好的電話。我在我編寫的任何新代碼中使用ArrayLists,但是有很多數組在我繼承的基礎上浮動。 – BostonJohn

1

雖然數組可以在for-each循環中使用,但它們不實現Iterable。只有兩種可能性,要麼按照您所說的那樣超載該方法,要麼只提供可迭代的變體並強制客戶端撥打Arrays.asList()

如果你也想提供陣列超載

,你可能會從簡單的數組改變其簽名,以可變參數:

public void foo(String... myStrings){ 
    foo(java.util.Arrays.asList(myStrings)); 
} 

在這種情況下,要注意基本數組和原始的方式包裝陣列之間的不相容性:

static void foo(int... ints) {} 
foo(new Integer[] {1, 2}); // compile error 

和:

static void foo(Integer... integers) {} 
foo(new int[] { 1, 2 }); // compile error 

而最晦澀一部分,與通用的可變參數:

static <T> T[] foo(T... ts) { 
    return ts; 
} 

如果傳遞整數數組:

Integer[] integers = { 1, 2 }; 
System.out.println(Arrays.deepToString(foo(integers))); 
> [1, 2] 

ts的值是整數的數組具有2個元素:12

然而,如果傳遞原始整數的數組,一個有趣的事情發生:

int[] ints = { 1, 2 }; 
System.out.println(Arrays.deepToString(foo(ints))); 
> [[1, 2]] 

在這種情況下,TS的值INT數組的數組(int[][])僅具有一個元素,該元素是最初傳入的數組。原因是int不是Object(自動裝箱在這裏沒有幫助),而int是一個數組,因此T類型參數的值變爲int[]

相關問題