Javaがサイズ0の配列を許可するのはなぜですか?


82

Javaの配列の長さは固定されています。では、なぜJavaはサイズ0の配列を許可するのですか?

String[] strings = new String[0];

回答:


122

それは空であることを意味します。つまり、アイテムがあるかのようにループして、結果が発生しないようにすることができます。

for(int k = 0; k < strings.length; k++){
   // something
}

これにより、チェックの必要がなくなります。問題の配列がのnull場合、例外が発生しますが、この場合は何も実行しないため、適切な場合があります。


9
また、関数test(Object... objects)がある場合に明示的に関数を呼び出す場合にも役立ちますtest()
Frithjof 2014年

51

Javaがサイズ1の配列を許可するのはなぜですか?単一の値を配列でラップするのはかなり役に立たないのではないですか?Javaがサイズ2以上の配列のみを許可するのであれば十分ではないでしょうか?

はい、null空の配列の代わりに渡すことができ、サイズ1の行列の代わりに単一のオブジェクトまたはプリミティブを渡すことができます。

しかし、そのような制限に反対するいくつかの良い議論があります。私の個人的なトップの議論:

制限が複雑すぎて、実際には必要ありません

配列をサイズ[1..INTEGER.MAX_INT]に制限するには、コードに多くの追加の境界チェック(Konradsのコメントに同意)変換ロジックとメソッドのオーバーロードを追加する必要があります。許可されたアレイサイズから0(およびおそらく1)を除外しても、コストを節約できず、追加の作業が必要になり、パフォーマンスに悪影響を及ぼします。

配列モデルベクトル

配列は、ベクターのための優れたデータモデルである(数学、ないVectorクラス!)。そしてもちろん、数学のベクトルはゼロ次元である可能性があります。これは、存在しないこととは概念的に異なります。


補足-(char-)配列の主要なラッパーはStringクラスです。不変Stringは空の配列の概念を具体化します:それは空の文字列("")です。


2
私はあなたの制限の議論を信じていません。Java(Cなどとは異なり)では、すでに負の数をチェックする必要があります。このチェックは、0に対応するように簡単に適合させることができます(に変更>= 0するだけ> 0です)。しかし、もちろん残りの部分については正しいので、この制限を追加しても意味がありません。
Konrad Rudolph

私の意見では、ループ反復引数の方が良いようです: "for(int k = 0; k <strings.length; k ++){//何か}"
dannyxyz22 2012

2
いいえ、私の意見ではありません。サイズがゼロの配列がない世界では、(char配列に基づく)空の文字列は単に存在しないため、ループ内の空の配列を考慮する必要はありません。この反復引数は非常に実用的な副作用です。その世界では、配列には少なくとも1つのエントリがあります。(または2つの理由:1つのアイテムに1つの配列が必要なのはなぜですか?)
Andreas Dolk 2012

負のインデックスと高すぎるインデックスのチェックは同じチェックです。負のインデックスは常に符号なしであり、配列の長さ以上です
harold 2018


16

これを考慮してください(正午の答えのより詳細な説明):

public String[] getStrings() {
 if( foo ) {
  return null;
 } else {
  return new String[] {"bar, "baz"};
 }
}

String[] strings = getStrings();
if (strings != null) {
 for (String s : strings) {
  blah(s);
 }
}

今それをこれと比較してください:

public String[] getStrings() {
 if( foo ) {
  return new String[0];
 } else {
  return new String[] {"bar, "baz"};
 }
}

// the if block is not necessary anymore
String[] strings = getStrings();
for (String s : strings) {
 blah(s);
}

これ(null値ではなく空の配列を返す)は、実際にはJavaAPI設計の世界でのベストプラクティスです。

さらに、Javaでは、リスト(ArrayListなど)を配列に変換できます。空のリストを空の配列に変換することだけが意味があります。



4

長さがゼロの配列が役立つ別のケース:リスト内のすべての要素を含む配列を返すには:

<T> T[ ] toArray(T[ ] a)

長さゼロの配列を使用して、配列のタイプをこのメソッドに渡すことができます。例えば:

ClassA[ ] result = list.toArray(new ClassA[0]);

長さがゼロの配列は、要素がゼロのObjectのインスタンスです。


2

空の配列が非常に役立つと思う1つのケースは、nullが許可されていない状況でnullの代わりにそれを使用することです。その1つの可能な例は、配列のBlockingQueueです。入力の終了を読み取り側に通知したい場合はどうしますか?nullを送信するのは当然の選択のように思えますが、BlockingQueueはnullを受け入れないということです。配列を " boolean last;"のようなフィールドでクラス内にラップすることもできますが、それは一種のやり過ぎです。空の(サイズがゼロの)配列を送信するのが最も合理的な選択のようです。


0

長さがゼロの配列が役立つもう1つのケースは、2次元配列をコピーする場合です。私は書くことができます:

public int[][] copyArray(int[][] array){
     int[][] newArray = new int[array.length][0];
     for(int i=0;i<array.length;i++){
         newArray[i] = array[i];
     }
     return newArray;

配列内のすべての配列参照が上書きされるため、長さがゼロの配列への参照としてそれらを初期化するのが最も効率的です。


0

A 0の長さbyte[]、またはchar[]空表すことができるStringとは別個であるが、null。(使用して文字列からアレイなどバイト、または文字を取得getBytes()getChars()Stringクラスなど)およびその逆の形成StringからSをbyte[]char[]非常に一般的です。たとえば、カスタムエンコーディングの場合、文字列のデコード。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.