Entendendo um ArrayList

Entendendo um ArrayList

Um array tem uma deficiência gritante: você precisa saber quantos elementos serão necessários no array ao criá-lo e, em seguida, você fica preso a essa escolha. Assim como um StringBuilder, um ArrayList pode alterar a capacidade em tempo de execução conforme necessário. Como um array, um ArrayList é uma sequência ordenada que permite duplicatas.

Como quando usamos Arrays.sort, ArrayList requer uma importação. ArrayList requer uma importação. Para usá-lo, você deve ter qualquer uma das duas declarações a seguir em sua classe:

Nesta seção, veremos como criar um ArrayList, métodos comuns, autoboxing, com versão e classificação.

Criando um ArrayList

Assim como no StringBuilder, existem três maneiras de criar um ArrayList:

A primeira diz para criar um ArrayList contendo espaço para o número padrão de elementos,mas não para preencher nenhuma posição ainda. A segunda diz para criar um ArrayList contendo um número específico de posições, mas novamente não para atribuir nenhum. O exemplo final diz a Java que nós desejamos fazer uma cópia de outro ArrayList. Copiamos o tamanho e o conteúdo desse ArrayList. Concedido, lista2 está vazia neste exemplo, então não é particularmente interessante.

Embora esses sejam os únicos três construtores que você precisa conhecer, você também precisa aprender algumas variantes deles. Os exemplos anteriores eram a antiga maneira pré-Java 5 de criar um ArrayList. Eles ainda funcionam e você ainda precisa saber que eles funcionam. Você também precisa saber a maneira nova e melhorada. O Java 5 introduziu os genéricos, que permitem especificar o tipo de classe que o ArrayList conterá.

O Java 5 permite que você diga ao compilador qual seria o tipo, especificando-o entre < e >. A partir do Java 7, você pode até omitir esse tipo do lado direito.  < e > ainda são necessários. Isso é chamado de operador diamante porque <> se parece com um diamante.

Usando var com ArrayList

Agora que var pode ser usado para ocultar tipos de dados, há todo um novo grupo de perguntas que pode ser feito com genéricos. Considere este código misturando os dois:

O tipo de var é ArrayList<String>. Isso significa que você pode adicionar uma String ou fazer um loop dos objetos String. E se usarmos o operador diamante com var?

Acredite ou não, isso compila. O tipo da var é ArrayList<object>. Desde que não haja um tipo especificado para o genérico, Java deve assumir a superclasse final.

Isso é um pouco bobo e inesperado, então, por favor, não escreva isso. Agora você pode descobrir por que isso não compila?

O tipo de var é ArrayList<Object). Como não há um tipo no operador diamante, Java tem que assumir a opção mais genérica possível. Portanto, ele escolhe Object, o último companheiro da superclasse. Adicionar uma String à lista é bom. Você pode adicionar qualquer subclasse de Object. No entanto, no loop, precisamos usar o tipo de objeto em vez de String.

Quando você pensou que sabia tudo sobre como criar um ArrayList, existem mais coisas que você precisa saber. ArrayList implementa uma interface chamada List. em outras palavras, um ArrayList é um List. Enquanto isso, saiba que você pode armazenar um ArrayList em uma variável de referência List, mas não vice-versa. A razão é que List é uma interface e as interfaces não podem ser instanciadas.

Usando um ArrayList

ArrayList tem muitos métodos, mas você só precisa conhecer um punhado deles, menos ainda do que você fez para String e StringBuilder. Antes de continuar lendo, você verá algo novo nas assinaturas de método: uma classe chamada E. Não se preocupe, não é realmente uma classe. E é usado por convenção em generics para significar "qualquer classe que este array pode conter".

Se você não especificou um tipo ao criar o ArrayList, E significa Objeto. Caso contrário, significa a classe que você quer entre < e >.

Você também deve saber que ArrayList implementa toString(), para que você possa ver facilmente o conteúdo apenas imprimindo-o. Arrays, não produzem uma saída tão bonita por padrão.

add()

Os métodos add() inserem um novo valor no ArrayList. As assinaturas do método são as seguintes:

Não se preocupe com o valor de retorno booleano. Sempre retorna verdadeiro. Ele está lá porque outras classes da família Collections precisam de um valor de retorno na assinatura ao adicionar um elemento. Como add () é o método ArrayList mais crítico que você precisa conhecer, nós vamos mostrar alguns exemplos disso. Vamos começar com o caso mais simples:

add() faz exatamente o que esperamos: armazena a String no espaço que não está mais vazio ArrayList. Em seguida, faz a mesma coisa para o booleano. Tudo bem, porque não especifiquei um tipo para ArrayList; portanto, o tipo é Object, que inclui tudo, exceto primitivos. Pode não ser o que pretendemos, mas o compilador não sabe. Agora, vamos usar genéricos para dizer ao compilador que queremos permitir apenas objetos String em nossa ArrayList:

Desta vez, o compilador sabe que apenas objetos String são permitidos e evita a tentativa de adicionar um booleano. Agora, vamos tentar adicionar vários valores a posições diferentes.

Quando uma pergunta tiver código que adiciona objetos em posições indexadas, desenhe-o de forma que você não perderá o controle de qual valor está em qual índice. Neste exemplo, a linha 5 adiciona "hawk" ao fim dos birds. Em seguida, a linha 6 adiciona “robin” ao índice 1 de birds, que é o fim.

A linha 7 adiciona “blue jay” ao índice 0, que é o início dos birds. Finalmente, a linha 8 adiciona “cardinal” ao índice 1, que agora está próximo ao meio dos birds.

remove()

Os métodos remove() removem o primeiro valor correspondente no ArrayList ou removem o elemento em um índice especificado. As assinaturas do método são as seguintes:

Desta vez, o valor de retorno booleano nos informa se uma correspondência foi removida. O tipo de retorno E é o elemento que realmente foi removido. Abaixo mostra como usar esses métodos:

A linha 6 tenta remover um elemento que não está nos birds. Ele retorna falso porque não existe tal elemento. A linha 7 tenta remover um elemento que está em birds e então retorna verdadeiro. Observe que ele remove apenas uma correspondência. A linha 8 remove o elemento no índice 0, que é o último elemento restante no ArrayList. Como chamar remove() com um int usa o índice, um índice que não existe lançará uma exceção. Por exemplo, birds.remove (100) lança uma IndexOutOfBoundsException. Também existe um método removeIf () que usa expressões lambda.

set()

O método set() altera um dos elementos do ArrayList sem alterar o tamanho.

A assinatura do método é a seguinte:

O tipo de retorno E é o elemento que foi substituído. O seguinte código mostra como usar este método:

A linha 16 adiciona um elemento ao array, tornando o tamanho 1. A linha 18 substitui esse elemento, e o tamanho permanece em 1. A linha 20 tenta substituir um elemento que não está no ArrayList. Como o tamanho é 1, o único índice válido é 0. Java lança uma exceção porque isso não é permitido.

isEmpty() e size()

Os métodos isEmpty() e size() analisam quantos espaços estão em uso. As assinaturas de métodos são as seguintes:

O seguinte código mostra como usar esses métodos:

No início, os birds têm tamanho 0 e estão vazios. Tem uma capacidade maior do que 0. No entanto, como acontece com StringBuilder, não usamos a capacidade para determinar o tamanho ou comprimento. Após adicionar elementos, o tamanho torna-se positivo e não fica mais vazio. Perceba como isEmpty() é um método de conveniência para size() == 0.

clear()

O método clear() fornece uma maneira fácil de descartar todos os elementos do ArrayList. A assinatura do método é a seguinte:

Depois de chamarmos clear(), os birds voltam a ser um ArrayList vazio de tamanho 0.

contains()

O método contains() verifica se um determinado valor está no ArrayList. A assinatura de método é a seguinte:

O seguinte mostra como usar este método:

Este método chama equals() em cada elemento do ArrayList para ver se há quaisquer correspondências. Como String implementa equals(), isso funciona bem.

equals()

Finalmente, ArrayList possui uma implementação personalizada de equals(), então você pode comparar duas listas para ver se eles contêm os mesmos elementos na mesma ordem.

O seguinte mostra um exemplo:

Na linha 33, os dois objetos ArrayList são iguais. Uma lista vazia é certamente o mesmo elemento na mesma ordem. Na linha 35, os objetos ArrayList não são iguais porque o tamanho é diferente. Na linha 37, eles são iguais novamente porque o mesmo elemento está em cada um. Na linha 40, eles não são iguais. O tamanho é o mesmo e os valores são os mesmos, mas não estão na mesma ordem.

Agora você está pronto para criar um ArrayList. Nos vemos no próximo artigo!

💡
As opiniões e comentários expressos neste artigo são de propriedade exclusiva de seu autor e não representam necessariamente o ponto de vista da Revelo.

A Revelo Content Network acolhe todas as raças, etnias, nacionalidades, credos, gêneros, orientações, pontos de vista e ideologias, desde que promovam diversidade, equidade, inclusão e crescimento na carreira dos profissionais de tecnologia.