Eu me pergunto por que java.util.ArrayList
permite adicionar null
. Existe algum caso em que eu gostaria de adicionar null
a um ArrayList
?
Estou fazendo essa pergunta porque, em um projeto, tivemos um bug em que algum código estava sendo adicionado null
ao arquivo ArrayList
e era difícil identificar onde estava o erro. Obviamente, um NullPointerException
foi lançado, mas não até outro código tentar acessar o elemento. O problema foi como localizar o código que adicionou o null
objeto. Teria sido mais fácil se houvesse ArrayList
uma exceção no código em que os elementos estavam sendo adicionados.
java
api-design
collections
Alfredo Osorio
fonte
fonte
null
maioria de suas coleções).null
é a maneira padrão de representar dados ausentes em Java, quer você goste ou não. De fato, muitas pessoas não gostam e fazem disso um argumento para coisas funcionais no estilo de programação. A resposta mais votada não faz sentido / não captura a essência do problema.null
é. "Missing" é apenas uma das várias interpretações possíveis denull
. Outras interpretações válidas podem ser "Desconhecido", "Não aplicável" ou "Não inicializado". O quenull
representa depende da aplicação. Como a comunidade Python diria: "Diante da ambiguidade, recuse a tentação de adivinhar". Recusar manter nulo em um contêiner perfeitamente capaz de fazer isso seria apenas isso - um palpite.Respostas:
Essa decisão de design aparece principalmente conduzida pela nomeação.
O nome ArrayList sugere a leitura de uma funcionalidade semelhante às matrizes - e é natural que os designers do Java Collections Framework esperem que a grande maioria dos usuários da API conte com ele funcionando de maneira semelhante às matrizes.
Isso, em particular, envolve o tratamento de elementos nulos. Usuário da API sabendo que abaixo funciona bem:
ficaria surpreso ao descobrir se código semelhante para ArrayList lançaria NPE:
O raciocínio como acima é apresentado no tutorial do JCF, enfatizando pontos que sugerem uma similaridade próxima entre ArrayList e matrizes simples:
Se você deseja que uma implementação da Lista não permita nulos, é melhor chamar isso
NonNullableArrayList
ou algo assim para evitar confundir os usuários da API.Nota lateral: há uma discussão auxiliar nos comentários abaixo, além de considerações adicionais que sustentam o raciocínio apresentado aqui.
fonte
LinkedList
também suportanull
entradas de lista.null
entradas é útil em muitos casos.Nulo pode ser um valor válido para um elemento de uma lista. Digamos que sua lista contenha elementos que representem alguns dados opcionais sobre uma lista de usuários e seja armazenada na mesma ordem que os usuários. Se os dados extras forem preenchidos, sua lista conterá os dados adicionais, caso contrário, o slot correspondente a um usuário será nulo. (Tenho certeza de que existem exemplos melhores, mas você entendeu)
se você não quiser permitir que nulos sejam adicionados, você pode agrupar a lista de matrizes com seu próprio invólucro, lançado quando o nulo foi adicionado.
fonte
ArrayList
permite nulo por design. É intencional. Do javadoc :A resposta para "por que" é que, se isso não acontecesse, o ArrayList não seria utilizável nos casos em que é necessário colocar um
null
na lista. Por outro lado, você pode impedir que um ArrayList contenha valores nulos testando valores antes de incluí-los ou usando um wrapper que impede que isso aconteça.Obviamente, qualquer caso em que
null
tenha um significado distinto. Por exemplo, pode significar que o valor em uma determinada posição na lista não foi inicializado ou fornecido.Você pode implementar esse comportamento facilmente criando uma classe de wrapper. No entanto, esse não é o comportamento que a maioria dos programadores / aplicativos precisa.
fonte
Existe algum caso em que eu gostaria de adicionar nulo a um ArrayList?
Claro, e a pré-alocação? Você quer
ArrayList
algumas coisas que ainda não pode criar porque não possui informações suficientes. Só porque você não consegue pensar em uma razão pela qual alguém pode querer fazer algo não a torna uma má idéia. Tanto faz. (Agora, tenho certeza de que alguém aparecerá e dirá que você deve ter objetos vazios que atendam a algum padrão sobre o qual leram em algum blog obscuro e que os programadores realmente possam escrever programas sem nunca usarif
declarações, blá, blá).Se vocês têm um contrato que nunca deve haver
null
s em um contêiner, é da sua responsabilidade garantir que o contrato seja cumprido, provavelmente de maneira mais apropriada, afirmando. Provavelmente levaria no máximo 10 linhas de código. Java torna incrivelmente fácil para você fazer esse tipo de coisa. O JDK não consegue ler sua mente.fonte
ensureCapacity(int minCapacity)
método e oArrayList(int initialCapacity)
construtor.null
nas entradas pré-alocadas (mas ainda não utilizadas ) doArrayList
; mas podemos deixarensureCapacity
fazer isso e ainda não permitir outras funções, comoset
fazê-lo. As razões apresentadas em outros lugares parecem mais fortes.set
um item com qualquer valor que possa ser retornadoget
. Mesmo se uma tentativa de normal aget
um item para que o espaço tinha sido atribuída, mas nunca escrito deve lançar uma exceção em vez de retornarnull
, ainda seria útil ter um par de métodos que permitirialist1.setOrEraseIfNull(index, list2.getOrReturnNull(index))
ao invés de exigirif (list2.valueSet(index)) list1.set(index, list2.get(index)); else list1.unset(index);
Isso parece ser mais uma questão filosófica (de software) aqui.
ArrayList
como uma classe de utilitário foi projetada para ser útil em um amplo contexto de possíveis casos de uso.Ao contrário de sua alegação oculta de que a aceitação de nulo como um valor válido deve ser desencorajada, há muitos exemplos em que o valor nulo é perfeitamente legal.
O motivo mais importante
null
é odo not know
equivalente a qualquer tipo de referência, incluindo os tipos de estrutura. Isso implica que nulo não pode ser substituído em nenhum caso por uma versão mais fluente donothing
valor.Então, digamos que você armazene os números inteiros 1, 3, 7 na sua lista de matrizes no índice correspondente: devido a alguns cálculos, você deseja obter o elemento no índice 5, então o que sua matriz deve retornar é: "nenhum valor armazenado". Isso pode ser alcançado retornando null ou um NullObject . Na maioria dos casos, o retorno do valor nulo incorporado é expressivo o suficiente. Depois de chamar um método que pode retornar nulo e usar seu valor de retorno, uma verificação do valor retornado contra nulo é bastante comum no código moderno.
fonte
A declaração
é válido e útil (acho que não preciso explicar o porquê). Da mesma forma, é útil ter uma coleção de arquivos, alguns dos quais podem ser nulos.
A utilidade de coleções que podem conter objetos nulos procede diretamente da utilidade de objetos que podem ser nulos. É realmente tão simples como isso.
fonte
É mais fácil aceitar tudo, do que ser restritivo e, em seguida, tente abrir seu design após o fato.
Por exemplo, e se o oracle / sun fornecesse apenas NonNullableArrayList, mas você quisesse adicionar um Null à sua lista. Como você faria? Você provavelmente teria que criar um objeto totalmente diferente; não seria possível estender o NonNullableArrayList. Em vez disso, se você tiver um ArrayList que aceita tudo, poderá estendê-lo facilmente e substituir o add, onde ele não aceita valores nulos.
fonte
Utilidade de nulo?
Muito quando você usa uma Lista de listas para modelar uma placa 2D da vida real com posições diferentes. Metade dessas posições pode estar vazia (em coordenadas aleatórias) enquanto as preenchidas não representam um int ou String simples, mas são representadas por um objeto complexo. Se você deseja manter as informações posicionais, preencha os espaços vazios com nulo, para que sua lista.get (x) .get (y)não leva a surpresas desagradáveis. Para combater as exceções nulas, você pode procurar nulas (muito populares) ou pode usar um opcional (que acho útil neste caso). A alternativa seria preencher os espaços vazios com objetos "lixo" que podem levar a todos os tipos de bagunça no caminho. Se sua verificação nula falhar ou for esquecida em algum lugar, o Java informará você. Por outro lado, um objeto de espaço reservado "lixo" que não é verificado corretamente pode passar despercebido.
fonte