Warum erlaubt Java Arrays der Größe 0?

81

Arrays in Java sind in der Länge festgelegt. Warum erlaubt Java dann Arrays der Größe 0?

String[] strings = new String[0];
Robbin
quelle

Antworten:

121

Es bedeutet, dass es leer ist. Dh Sie können es durchlaufen, als ob es Elemente hätte und kein Ergebnis auftreten würde:

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

Dadurch wird die Notwendigkeit einer Überprüfung vermieden. Wenn das fragliche Array nullwäre, würde eine Ausnahme auftreten, aber in diesem Fall tut es einfach nichts, was angemessen sein könnte.

Mittags Seide
quelle
9
Es ist auch nützlich, um eine Funktion test(Object... objects)explizit aufzurufen, wenn es eine Funktion gibttest()
Frithjof
50

Warum erlaubt Java Arrays der Größe 1? Ist es nicht ziemlich nutzlos, einen einzelnen Wert in ein Array zu packen? Wäre es nicht ausreichend, wenn Java nur Arrays der Größe 2 oder höher zulässt?

Ja, wir können nullanstelle eines leeren Arrays und eines einzelnen Objekts oder Grundelements anstelle einer Matrix der Größe eins übergeben.

Es gibt jedoch einige gute Argumente gegen eine solche Einschränkung. Meine persönlichen Top-Argumente:

Einschränkung ist zu kompliziert und nicht wirklich notwendig

Um Arrays auf die Größe [1..INTEGER.MAX_INT] zu beschränken, müssten wir unserem Code viele zusätzliche Boudary-Checks (Konrads Kommentar zustimmen), Konvertierungslogik und Methodenüberladungen hinzufügen . Das Ausschließen von 0 (und möglicherweise 1) von den zulässigen Array-Größen spart keine Kosten, erfordert zusätzlichen Aufwand und wirkt sich negativ auf die Leistung aus.

Array-Modellvektor

Ein Array ist ein gutes Datenmodell für einen Vektor (Mathematik, nicht die VectorKlasse!). Und natürlich kann ein Vektor in der Mathematik nulldimensional sein. Was sich konzeptionell von der Nichtexistenz unterscheidet.


Nebenbemerkung - ein prominenter Wrapper für ein (Zeichen-) Array ist die StringKlasse. Das Unveränderliche Stringmaterialisiert das Konzept eines leeren Arrays: Es ist der leere String ( "").

Andreas Dolk
quelle
2
Ich glaube Ihrem Restriktionsargument nicht. Java (im Gegensatz zu z. B. C) erfordert bereits eine Überprüfung auf negative Zahlen. Diese Überprüfung könnte trivialer angepasst werden 0 zu empfangen (nur ändern >= 0zu > 0). Aber Sie haben natürlich Recht mit dem Rest, daher wäre es nicht sinnvoll, diese Einschränkung hinzuzufügen.
Konrad Rudolph
Das Argument der Schleifeniteration scheint meiner Meinung nach besser zu sein: "für (int k = 0; k <strings.length; k ++) {// etwas}"
dannyxyz22
2
Nein, das ist meiner Meinung nach nicht der Fall, denn in einer Welt ohne Arrays mit der Größe Null würden leere Zeichenfolgen (basierend auf char-Arrays) einfach nicht existieren und es wäre daher nicht erforderlich, leere Arrays in Schleifen zu berücksichtigen. Dieses Iterationsargument ist ein sehr praktischer Nebeneffekt. In dieser Welt hätte ein Array mindestens einen Eintrag. (Oder zwei, weil: warum sollte man ein Array für nur ein Element benötigen?)
Andreas Dolk
Die Prüfung auf einen negativen Index und einen zu hohen Index ist die gleiche Prüfung: Negative Indizes sind immer ohne Vorzeichen - nicht weniger als die Länge des Arrays
Harold
25

Manchmal ist es viel freundlicher, ein Array mit der Größe Null als Null zurückzugeben.

Auf Freund
quelle
9
Dies wird als "Null-Objekt" -Muster bezeichnet.
Aleksandr Dubinsky
14

Betrachten Sie dies (eine detailliertere Erklärung der Antwort von Noon):

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

Vergleichen Sie es jetzt damit:

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

Dies (Rückgabe leerer Arrays anstelle von Nullwerten) ist in der Java API-Designwelt eine bewährte Methode.

Außerdem können Sie in Java Listen (z. B. ArrayList) in Arrays umwandeln, und es ist nur sinnvoll, eine leere Liste in ein leeres Array zu konvertieren.

βξhrαng
quelle
5

Wie C ++ ermöglicht es eine sauberere Handhabung, wenn keine Daten vorhanden sind.

Dan McGrath
quelle
4

Ein weiterer Fall, in dem ein Array mit der Länge Null nützlich sein kann: So geben Sie ein Array zurück, das alle Elemente in einer Liste enthält:

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

Ein Array mit der Länge Null kann verwendet werden, um den Typ des Arrays an diese Methode zu übergeben. Zum Beispiel:

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

Ein Array mit der Länge Null ist immer noch eine Instanz von Object, die Nullelemente enthält.

Don Li
quelle
2

Ein Fall, in dem ich mir vorstellen kann, wo ein leeres Array äußerst nützlich ist, ist die Verwendung anstelle von Null in einer Situation, in der Null nicht zulässig ist. Ein mögliches Beispiel hierfür ist eine BlockingQueue von Arrays. Was würden Sie tun, wenn Sie der Leseseite das Ende der Eingabe signalisieren möchten? Das Senden von Null scheint eine naheliegende Wahl zu sein, aber die Sache ist, dass BlockingQueue keine Nullen akzeptiert. Sie könnten Ihr Array in eine Klasse mit " boolean last;" Feld einschließen, aber das ist eine Art Overkill. Das Senden eines leeren Arrays (Größe Null) scheint die vernünftigste Wahl zu sein.

Sergei Tachenov
quelle
0

Ein anderer Fall, in dem ein Array mit der Länge Null nützlich ist, ist das Kopieren eines zweidimensionalen Arrays. Ich kann schreiben:

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;

Da jede Array-Referenz im Array überschrieben wird, ist es am effizientesten, sie als Verweise auf Arrays mit der Länge Null zu initialisieren.

Schachprogrammierer
quelle
0

Eine 0-Länge byte[]oder char[]kann eine leere darstellen String, die sich von unterscheidet null. Abrufen den Bytes oder Zeichen, als Arrays von Strings (unter Verwendung getBytes(), getChars()der StringKlasse etc.) und die umgekehrt zur Bildung Stringvon s byte[], char[]ist durchaus üblich. Zum Beispiel für die benutzerdefinierte Codierung, Decodierung von Zeichenfolgen.

Madhu
quelle