Me pregunto por qué java.util.ArrayListpermite agregar null. ¿Hay algún caso en el que me gustaría agregar nulla un ArrayList?
Me hago esta pregunta porque en un proyecto que teníamos un error en algún código se agregó nulla la ArrayListy era difícil de detectar dónde estaba el error. Obviamente NullPointerExceptionse 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 nullobjeto. Hubiera sido más fácil si hubiera ArrayListuna excepción en el código donde se agregaban los elementos.
                    
                        java
                                api-design
                                collections
                                
                    
                    
                        Alfredo Osorio
fuente
                
                fuente

nullen la mayoría de sus colecciones).nulles 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.nulles. "Missing" es solo una de varias interpretaciones potenciales denull. Otras interpretaciones válidas pueden ser "Desconocido", "No aplicable" o "No inicializado". Lo quenullrepresenta 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í
NonNullableArrayListo 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
LinkedListtambién admitenullentradas de lista.nullentradas 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
ArrayListpermite 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
nullen 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
nulltiene 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
ArrayListde 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 nuncaifdeclaraciones, bla, bla).Si ustedes tienen un contrato que nunca debe haber
nulls 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.nullen las entradas preasignadas (pero aún no utilizadas ) deArrayList; pero podemos dejar deensureCapacityhacer eso y, sin embargo, no permitir otras funciones comosethacerlo. Las razones dadas en otros lugares parecen más fuertes.setun artículo tenga cualquier valor que pueda devolverget. Incluso si un intento normal degetun 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í.
ArrayListcomo 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
nulles eldo not knowequivalente 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 delnothingvalor.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