12

いくつかの文字列を受け取り、それらを使って何かを行う関数を作成しようとしています。

文字列のセットがそれらをループすることだけを実行します。今、私はの線に沿って厄介な構造になってしまいます

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

String[]型のmyStringsに対して完全に有効なコードになります。

コレクションと配列の両方を許可するfooに受け入れさせることができるクラスはありますか?

4

3 に答える 3

11

配列を Iterable に代入できないのはなぜですか? を参照してください。

短い答え:いいえ。私が理解しているように、配列型は合成コードであるため、Iterable他の型を実装していません。Arrays.asListオーバーロードされたメソッドを提供するか、クライアントが呼び出しサイトで呼び出す必要があります。

于 2012-12-10T18:48:30.953 に答える
3

Iterable残念ながら、 for-each ループが両方で機能しているにもかかわらず、array は を実装していません。

配列を渡すことは少し古い学校であるため、排他的にのみ受け入れることができIterableます(配列のパフォーマンス上の利点ArrayListはごくわずかです)。既存の配列は簡単にラップしてListusingに変換できますArrays.asList(T... a)

于 2012-12-10T18:48:46.360 に答える
2

配列はfor-eachループで使用できますが、を実装していませんIterable。単純に2つの可能性があります。前述のようにメソッドをオーバーロードするか、反復可能なバリアントのみを提供してクライアントに強制的に呼び出すかのいずれかですArrays.asList()

配列のオーバーロードも提供する場合は、そのシグネチャを単純な配列からvarargsに変更できます。

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

そして、一般的なvarargsを使用した、最もあいまいな部分:

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の配列を渡すと、面白いことが起こります。

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

int[][]この場合、tsの値は、最初に渡された配列である1つの要素のみを持つint配列( )の配列です。この理由は、intの配列がであるのに対し、anintはではないObject(自動ボクシングはここでは役に立ちません)ため、Ttypeパラメーターの値はになりint[]ます。

于 2012-12-10T19:04:52.797 に答える