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

Las matrices en Java están fijadas en longitud. ¿Por qué Java permite matrices de tamaño 0 entonces?

String[] strings = new String[0]; 

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

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

De esta manera evitando la necesidad de verificar. Si la matriz en cuestión fuera null , se produciría una excepción, pero en este caso simplemente no hace nada, lo que puede ser apropiado.

¿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 arreglos de tamaño 2 o superior?

Sí, podemos pasar null lugar de una matriz vacía y un solo objeto o primitiva 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 los tamaños [1..INTEGER.MAX_INT] tendríamos que añadir un montón de comprobaciones de boudary adicionales, (de acuerdo con el comentario de Konrads) de la lógica de conversión y las sobrecargas de métodos de 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 (¡las matemáticas, no la clase Vector !). Y, por supuesto, un vector en matemáticas puede ser cero dimensional. Lo cual es conceptualmente diferente de ser inexistente.


Sidenote : una envoltura prominente para una matriz (char) es la clase String . La String inmutable materializa el concepto de una matriz vacía: es la cadena vacía ( "" ).

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

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áralo 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 mejor práctica en el mundo del diseño de la 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.

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

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

  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 cero elementos.

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

solo una nota:

Usted dice: “A diferencia de C, donde puede boost dinámicamente el tamaño de una matriz, …” pero en C no puede cambiar la dimensión de la matriz, lo mismo para C ++.

Otro caso cuando 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 

Siendo que todas las referencias de matriz en matriz se sobrescriben, inicializarlas como referencias a matrices de longitud cero es más eficiente.

Un byte[] longitud 0 byte[] , o char[] puede representar una String vacía, que es distinta de null . Obtener los bytes, o caracteres, como matrices de cadenas (usando getBytes() , getChars() de clase String , etc.) y viceversa de formar String s desde byte[] , char[] es bastante común. Por ejemplo, para la encoding personalizada, deencoding de cadenas.