¿Por qué Java permite matrices de tamaño 0?

82

Las matrices en java tienen una longitud fija. Entonces, ¿por qué Java permite matrices de tamaño 0?

String[] strings = new String[0];
robbin
fuente

Respuestas:

122

Significa que está vacío. Es decir, puede recorrerlo como si tuviera elementos y no se produce ningún resultado:

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

Evitando así la necesidad de comprobar. Si la matriz en cuestión lo fuera null, se produciría una excepción, pero en este caso simplemente no hace nada, lo que puede ser apropiado.

Seda del mediodía
fuente
9
También es útil para llamar test(Object... objects)explícitamente a una función cuando hay una funcióntest()
Frithjof
51

¿Por qué Java permite matrices de tamaño 1? ¿No es bastante inútil envolver un solo valor en una matriz? ¿No sería suficiente si Java solo permitiera matrices de tamaño 2 o mayor?

Sí, podemos pasar en nulllugar de una matriz vacía y un único objeto o primitivo en lugar de una matriz de tamaño uno.

Pero hay algunos buenos argumentos en contra de tal restricción. Mis principales argumentos personales:

La restricción es demasiado complicada y no es realmente necesaria

Para limitar las matrices a tamaños [1..INTEGER.MAX_INT] tendríamos que agregar muchas comprobaciones adicionales, (de acuerdo con el comentario de Konrads) lógica de conversión y sobrecargas de métodos a nuestro código. Excluir 0 (y quizás 1) de los tamaños de matriz permitidos no ahorra costos, requiere un esfuerzo adicional y tiene un impacto negativo en el rendimiento.

Vector de modelos de matriz

Una matriz es un buen modelo de datos para un vector (¡matemáticas, no la Vectorclase!). Y, por supuesto, un vector en matemáticas puede ser de dimensión cero. Que es conceptualmente diferente de ser inexistente.


Nota al margen : una envoltura prominente para una matriz (char-) es la Stringclase. Lo inmutable Stringmaterializa el concepto de arreglo vacío: es el String vacío ( "").

Andreas Dolk
fuente
2
No creo en tu argumento de restricción. Java (a diferencia de, por ejemplo, C) ya requiere una verificación de números negativos. Esta comprobación podría adaptarse trivialmente para acomodar 0 (simplemente cambie >= 0a > 0). Pero, por supuesto, tiene razón sobre el resto, por lo que agregar esta restricción no sería significativo.
Konrad Rudolph
El argumento de iteración de bucle parece mejor en mi opinión: "for (int k = 0; k <strings.length; k ++) {// algo}"
dannyxyz22
2
No, no lo es en mi opinión, porque en un mundo sin matrices de tamaño cero, las cadenas vacías (basadas en matrices de caracteres) simplemente no existirían y, por lo tanto, no habría necesidad de considerar matrices vacías en bucles. Este argumento de iteración es un efecto secundario muy práctico. En ese mundo, una matriz tendría una entrada como mínimo. (O dos porque: ¿por qué se necesitaría una matriz para un solo elemento?)
Andreas Dolk
La verificación de un índice negativo y un índice demasiado alto son la misma verificación: los índices negativos siempre están sin firmar, no menos que la longitud de la matriz
harold
26

A veces es mucho más amigable devolver una matriz de tamaño cero que nula.

En Freund
fuente
9
Esto se denomina patrón "Objeto nulo".
Aleksandr Dubinsky
16

Considere esto (una explicación más detallada de la respuesta de 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);
 }
}

Ahora compárelo con esto:

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

Esto (devolver matrices vacías en lugar de valores nulos) es de hecho una de las mejores prácticas en el mundo del diseño de API de Java.

Además, en Java, puede convertir Listas (por ejemplo, ArrayList) en matrices y solo tiene sentido convertir una lista vacía en una matriz vacía.

βξhrαng
fuente
5

Al igual que C ++, permite un manejo más limpio cuando no hay datos.

Dan McGrath
fuente
4

Otro caso en el que una matriz de longitud cero puede ser útil: para devolver una matriz que contiene todos los elementos de una lista:

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

Se puede usar una matriz de longitud cero para pasar el tipo de matriz a este método. Por ejemplo:

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

Una matriz de longitud cero sigue siendo una instancia de Object que contiene elementos cero.

Don Li
fuente
2

Un caso en el que puedo pensar en el que una matriz vacía es extremadamente útil es usarla en lugar de nulo en una situación en la que no se permite nulo. Un posible ejemplo de eso es un BlockingQueue de matrices. Cuando desee señalar el final de la entrada al lado de lectura, ¿qué haría? Enviar nulos parece una opción obvia, pero el problema es que BlockingQueue no acepta nulos. Podrías envolver tu arreglo dentro de una clase con " boolean last;" tipo de campo, pero eso es un poco exagerado. Enviar una matriz vacía (de tamaño cero) parece la opción más razonable.

Sergei Tachenov
fuente
0

Otro caso en el que una matriz de longitud cero es útil es cuando se copia una matriz bidimensional. Puedo escribir:

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;

Dado que cada referencia de matriz en la matriz se sobrescribe, es más eficiente inicializarlas como referencias a matrices de longitud cero.

programador de ajedrez
fuente
0

Una longitud 0 byte[], o char[]puede representar un vacío String, que es distinto de null. Obtener los bytes, o caracteres, como matrices de cadenas (usando getBytes(), getChars()de Stringclase, etc.) y viceversa de formar Strings byte[], char[]es bastante común. Por ejemplo, para codificación personalizada, decodificación de cadenas.

Madhu
fuente