Me pregunto por qué java.util.ArrayList
permite agregar null
. ¿Hay algún caso en el que me gustaría agregar null
a un ArrayList
?
Me hago esta pregunta porque en un proyecto que teníamos un error en algún código se agregó null
a la ArrayList
y era difícil de detectar dónde estaba el error. Obviamente NullPointerException
se arrojó un pero no hasta que otro código intentó acceder al elemento. El problema era cómo localizar el código que agregaba el null
objeto. Hubiera sido más fácil si hubiera ArrayList
una excepción en el código donde se agregaban los elementos.
java
api-design
collections
Alfredo Osorio
fuente
fuente
null
en la mayoría de sus colecciones).null
es la forma predeterminada de representar los datos faltantes en Java, te guste o no. De hecho, a mucha gente no le gusta y lo convierte en un argumento para cosas de estilo de programación funcional. La respuesta más votada no tiene sentido / no captura la esencia del problema.null
es. "Missing" es solo una de varias interpretaciones potenciales denull
. Otras interpretaciones válidas pueden ser "Desconocido", "No aplicable" o "No inicializado". Lo quenull
representa depende de la aplicación. Como diría la comunidad de Python: "Ante la ambigüedad, rechace la tentación de adivinar". Negarse a mantener nulo en un contenedor que sea perfectamente capaz de hacerlo sería solo eso, una suposición.Respuestas:
Esta decisión de diseño parece principalmente impulsada por los nombres.
Name ArrayList sugiere al lector una funcionalidad similar a las matrices , y es natural que los diseñadores de Java Collections Framework esperen que la gran mayoría de los usuarios de API confíen en que funcione de manera similar a las matrices.
Esto en particular, implica el tratamiento de elementos nulos. El usuario de la API sabe que a continuación funciona bien:
estaría bastante sorprendido de descubrir si un código similar para ArrayList arrojaría NPE:
El razonamiento como el anterior se presenta en los puntos de énfasis del tutorial JCF que sugieren una gran similitud entre ArrayList y las matrices simples:
Si desea una implementación de Lista que no permita nulos, será mejor que se llame así
NonNullableArrayList
o algo así, para evitar confundir a los usuarios de API.Nota al margen hay una discusión auxiliar en los comentarios a continuación, junto con consideraciones adicionales que respaldan el razonamiento aquí expuesto.
fuente
LinkedList
también admitenull
entradas de lista.null
entradas es útil en muchos casos.Nulo puede ser un valor válido para un elemento de una lista. Digamos que su lista contiene elementos que representan algunos datos opcionales sobre una lista de usuarios y se almacena en el mismo orden que los usuarios. Si se rellenan los datos adicionales, su lista contendrá los datos adicionales; de lo contrario, el espacio correspondiente a un usuario será nulo. (Estoy seguro de que hay mejores ejemplos, pero entiendes la idea)
si no desea permitir que se agreguen nulos, puede ajustar la lista de matrices con su propio contenedor que arrojó cuando se agregó nulo.
fuente
ArrayList
permite nulo por diseño. Es intencional. Desde el javadoc :La respuesta a "por qué" es que si no fuera así, ArrayList no sería utilizable en los casos en que sea necesario poner un
null
en la lista. Por el contrario, puede evitar que un ArrayList contenga valores nulos probando los valores antes de agregarlos o utilizando un contenedor que evite que esto suceda.Obviamente, cualquier caso donde
null
tiene un significado distinto. Por ejemplo, podría significar que el valor en una posición dada en la lista no se ha inicializado o suministrado.Puede implementar fácilmente ese comportamiento creando una clase de contenedor. Sin embargo, este no es el comportamiento que necesitan la mayoría de los programadores / aplicaciones.
fuente
¿Hay algún caso en el que me gustaría agregar nulo a una ArrayList?
Claro, ¿qué pasa con la preasignación? Desea una
ArrayList
de las cosas que aún no puede crear porque no tiene suficiente información. El hecho de que no se te ocurra una razón por la que alguien quiera hacer algo no lo convierte en una mala idea. Lo que sea. (Ahora, estoy seguro de que alguien vendrá y dirá que en su lugar debería tener objetos vacíos que cumplan con algún patrón sobre el que leyeron en algún blog oscuro y que los programadores realmente deberían poder escribir programas sin usar nuncaif
declaraciones, bla, bla).Si ustedes tienen un contrato que nunca debe haber
null
s en un contenedor, entonces depende de usted asegurarse de que se cumpla el contrato, probablemente lo más apropiado al afirmarlo. Probablemente te hubiera tomado un máximo de 10 líneas de código. Java te hace increíblemente fácil hacer este tipo de cosas. El JDK no puede leer tu mente.fuente
ensureCapacity(int minCapacity)
método y elArrayList(int initialCapacity)
constructor.null
en las entradas preasignadas (pero aún no utilizadas ) deArrayList
; pero podemos dejar deensureCapacity
hacer eso y, sin embargo, no permitir otras funciones comoset
hacerlo. Las razones dadas en otros lugares parecen más fuertes.set
un artículo tenga cualquier valor que pueda devolverget
. Incluso si un intento normal deget
un elemento para el que se ha asignado espacio pero nunca escrito debería arrojar una excepción en lugar de regresarnull
, aún sería útil tener un par de métodos que permitirían enlist1.setOrEraseIfNull(index, list2.getOrReturnNull(index))
lugar de requeririf (list2.valueSet(index)) list1.set(index, list2.get(index)); else list1.unset(index);
Esto parece ser más una pregunta filosófica (software) aquí.
ArrayList
como una clase de utilidad está diseñada para ser útil en un amplio contexto de posibles casos de uso.Contrariamente a su afirmación oculta de que no se debe aceptar aceptar nulo como valor válido, hay muchos ejemplos en los que el valor nulo es perfectamente legal.
La razón más importante es que
null
es eldo not know
equivalente de cualquier tipo de referencia, incluidos los tipos de marco. Esto implica que nulo no puede ser reemplazado en ningún caso por una versión más fluida delnothing
valor.Entonces, supongamos que almacena los números enteros 1, 3, 7 en su lista de arrays en su índice correspondiente: debido a algunos cálculos, desea obtener el elemento en el índice 5, por lo que su matriz debería devolver: "ningún valor almacenado". Esto podría lograrse devolviendo nulo o un objeto nulo . En la mayoría de los casos, devolver el valor nulo incorporado es suficientemente expresivo. Después de llamar a un método que puede devolver nulo y usar su valor de retorno, una verificación del valor devuelto contra nulo es bastante común en el código moderno.
fuente
La declaración
es válido y útil (no creo que necesite explicar por qué). También es útil tener una colección de archivos, algunos de los cuales pueden ser nulos.
La utilidad de las colecciones que pueden contener objetos nulos procede directamente de la utilidad de los objetos que pueden ser nulos. Es realmente así de simple.
fuente
Es más fácil aceptar todo, que ser restrictivo y luego intentar abrir su diseño después del hecho.
Por ejemplo, ¿qué pasaría si oracle / sun proporcionara solo NonNullableArrayList, pero quisiera poder agregar un Nulo a su lista? ¿Como lo harias? Probablemente tendría que crear un objeto completamente diferente, no podría usar extender la NonNullableArrayList. En cambio, si tiene una ArrayList que toma todo, podría extenderla fácilmente y anular la adición, donde no acepta valores nulos.
fuente
Utilidad de nulo?
Mucho más cuando vas con una Lista de Listas para modelar una placa de la vida real en 2D con diferentes posiciones. La mitad de esas posiciones podrían estar vacías (en coordenadas aleatorias) mientras que las ocupadas no representan un int o String simple, sino que están representadas por un objeto complejo. Si desea mantener la información posicional, debe llenar los espacios vacíos con nulos para que su lista.get (x) .get (y)no conduce a sorpresas desagradables. Para contrarrestar las excepciones nulas, puede verificar nulo (muy popular) o puede usar un Opcional (que me parece útil en este caso). La alternativa sería llenar los espacios vacíos con objetos "basura" que pueden conducir a todo tipo de desorden en el camino. Si su cheque nulo falla o se olvida en alguna parte, Java se lo informará. Por otro lado, un objeto de marcador de posición "basura" que no se verifica correctamente puede pasar desapercibido.
fuente