DEV Community

Yesmin Marie Soret Lahoud
Yesmin Marie Soret Lahoud

Posted on • Edited on

Utilização da Classe ArrayList do Java para Manipulação de Vetores

Neste artigo vou apresentar algumas características da classe ArrayList do Java e demonstrar a utilização de alguns dos métodos mais utilizados.

Por que utilizar a classe ArrayList?

Quando utilizamos o array padrão do Java, precisamos determinar qual será o seu tamanho no momento de sua criação. Esse tamanho é fixo e, uma vez criado, não conseguimos alterar o número de elementos. Se por exemplo, precisarmos adicionar mais um elemento, é necessário criar um novo array e copiar todos os elementos que estão no antigo array para o novo. Essa prática acaba sendo muito trabalhosa e também provoca uma perda de desempenho.

A classe ArrayList serve justamente para solucionar esse problema, pois ela permite que sejam criados arrays dinâmicos, ou seja, se precisarmos adicionar mais um elemento, o ArrayList faz esse redimensionamento de forma automática.

Hierarquia da Classe ArrayList

A classe ArrayList faz parte do Java Collections, que pertence ao pacote java.util. O ArrayList é uma implementação da interface List, que por sua vez estende a interface Collection. No diagrama abaixo, as linhas cheias representam “extends” e as linhas pontilhadas “implements”:

Image description

Além dos métodos herdados de Collection, a interface List fornece métodos que permitem a manipulação de elementos com base na posição (ou índice) em que eles se encontram. Assim como nos vetores, o índice começa em zero.

Alguns dos principais métodos

  • add(item) -> adiciona um novo elemento ao ArrayList. O elemento é inserido no final da lista;
  • add(posição, item) -> insere o elemento em uma posição específica da lista;
  • remove(posição) -> remove o elemento de uma determinada posição da lista;
  • set(posição, item) -> substitui um elemento em uma posição específica;
  • get(posição) -> retorna o elemento da posição especificada;
  • indexOf(item) -> retorna a posição da primeira ocorrência do elemento especificado;
  • contains(item) -> retorna verdadeiro caso a lista contenha o elemento especificado. Caso contrário, retorna falso;
  • clear() -> remove todos os elementos da lista;
  • isEmpty()-> retorna verdadeiro se a lista estiver vazia. Caso contrário retorna falso;
  • size()-> retorna a quantidade de elementos da lista.

Formas de inicializar um ArrayList

Podemos inicializar o ArrayList sem especificar o tipo dos elementos que a lista conterá, como mostrado a seguir:

ArrayList lista = new ArrayList();
Enter fullscreen mode Exit fullscreen mode

Esse formato permite que adicionemos elementos de qualquer tipo na lista. No exemplo abaixo, repare que os tipos dos dados inseridos estão misturados:

import java.util.ArrayList;

public class TesteArrayList {
    public static void main(String[] args) {
        ArrayList lista = new ArrayList();
        lista.add("Ana");
        lista.add(123);
        lista.add("Maria");
        lista.add(12.34);
        lista.add("Paulo");

        System.out.println(lista);
    }
}

Enter fullscreen mode Exit fullscreen mode

Saída:

[Ana, 123, Maria, 12.34, Paulo]
Enter fullscreen mode Exit fullscreen mode

Se por exemplo, precisássemos armazenar o elemento de determinada posição em uma variável, seria necessário fazer o type cast, indicando o tipo do Objeto. No exemplo abaixo, estamos tentando armazenar o elemento da posição 1 na String nome, no entanto esse elemento é um valor inteiro(123), o que acabará causando um “run time exception” no momento da execução.

import java.util.ArrayList;

public class TesteArrayList {
    public static void main(String[] args) {
        ArrayList lista = new ArrayList();
        lista.add("Ana");
        lista.add(123);
        lista.add("Maria");
        lista.add(12.34);
        lista.add("Paulo");

        // vai causar run time exception, 
        // pois o elemento da posição 1 é um inteiro(123)
        String nome = (String) lista.get(1); 

        System.out.println(lista);
    }
}

Enter fullscreen mode Exit fullscreen mode

Saída:

java.lang.ClassCastException
class java.lang.Integer cannot be cast to class java.lang.String
Enter fullscreen mode Exit fullscreen mode

Portanto, para evitar problemas, o ideal é não permitirmos que o ArrayList armazene elementos com tipos misturados. Para limitar o ArrayList podemos usar o Generics, inserindo o tipo de objeto que a lista irá armazenar.

Obs.: Não são aceitos tipos primitivos. Por exemplo, para inserir valores inteiros, usamos Integer ao invés de int.

ArrayList<Integer> lista = new ArrayList<>();
Enter fullscreen mode Exit fullscreen mode

Veja um exemplo em que criamos uma lista de elementos inteiros.

import java.util.ArrayList;

public class TesteArrayList {
    public static void main(String[] args) {
        ArrayList<Integer> lista = new ArrayList<>();
        lista.add(1);
        lista.add(2);
        lista.add(3);

        System.out.println(lista);
    }
}

Enter fullscreen mode Exit fullscreen mode

Saída:

[1, 2, 3] 
Enter fullscreen mode Exit fullscreen mode

Podemos também utilizar o polimorfismo e declarar uma referência da interface List e instanciar a classe ArrayList.

List<Integer> lista = new ArrayList<>();
Enter fullscreen mode Exit fullscreen mode

A vantagem de declararmos o ArrayList desta maneira é que podemos a qualquer momento, caso seja necessário, alterar a classe que implementa a interface List. Por exemplo, ao invés de utilizar a classe ArrayList podemos optar por usar a LinkedList ou a Vector, pois ambas implementam a interface List.

List<Integer> lista = new LinkedList<>();
Enter fullscreen mode Exit fullscreen mode

Caso já saibamos quantos elementos o array terá, podemos passar a capacidade inicial por parâmetro no construtor. Isso é muito recomendado nestes casos, pois evitamos desperdício de memória. No exemplo abaixo, estamos iniciando nosso ArrayList com 5 posições. Caso seja necessário adicionar mais elementos posteriormente, o redimensionamento é feito de forma automática.

List<String> lista = new ArrayList<>(5);
Enter fullscreen mode Exit fullscreen mode

Podemos ainda criar uma lista a partir de outra já existente. Basta passarmos a lista base por parâmetro no construtor:

List<String> lista = new ArrayList<>(5);
lista.add("Maria");
lista.add("Pedro");
List<String> novaLista = new ArrayList<>(lista);
Enter fullscreen mode Exit fullscreen mode

Exemplo de como utilizar ArrayList

No exemplo a seguir, será demonstrado como usar alguns dos métodos fornecidos pela classe ArrayList.

  1. Primeiro, vamos instanciar uma lista;
  2. Depois, vamos adicionar cinco cidades usando o método add(item);
  3. Percorreremos a lista e exibiremos essas cidades usando o for. Aqui serão utilizados os métodos get(posição) e size();
  4. Com o método remove(posição), removeremos a cidade da posição 3 (Manaus);
  5. Com o método add(posição, item), adicionaremos a cidade “Florianópolis” na posição zero;
  6. Vamos percorrer novamente a lista usando for-each;
  7. Agora usaremos o indexOf(item) para retornar a posição da cidade “Recife” e, com o método set(posição, item) substituiremos “Recife” por “Salvador”;
  8. Agora vamos percorrer a lista novamente, mas usando Iterator. (O Iterator é um padrão de projeto que permite iterar entre os elementos dentro da coleção).
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

public class TesteArrayList {
    public static void main(String[] args) {

        // 1) Primeiro, vamos instanciar uma lista;
        List<String> cidades = new ArrayList<>();

        // 2) Depois, vamos adicionar cinco cidades 
        // usando o método add(item);
        cidades.add("São Paulo");
        cidades.add("Rio de Janeiro");
        cidades.add("Recife");
        cidades.add("Manaus");
        cidades.add("Curitiba");

        // 3) Percorreremos a lista e exibiremos 
        // essas cidades usando o for.
        // Aqui serão utilizados os métodos get(posição) e size()
        System.out.println("Percorrendo a lista usando for:");
        for(int i = 0; i < cidades.size(); i++){
            System.out.println("Posição " + i + " - " + cidades.get(i));
        }

        // 4) Com o método remove(posição), 
        // removeremos a cidade da posição 3 (Manaus);
        cidades.remove(3);

        // 5) Com o método add(posição, item), 
        // adicionaremos a cidade “Florianópolis” na posição zero;
        cidades.add(0, "Florianópolis");

        // 6) Vamos percorrer novamente a lista usando for-each;
        System.out.println("==================");
        System.out.println("Percorrendo a lista usando for-each:");
        int i = 0;
        for(String cidade : cidades){
            System.out.println("Posição " + i + " - " + cidade);
            i++;
        }

        // 7) Agora usaremos o indexOf(item) para retornar 
        // a posição da cidade “Recife” e, com o método 
        // set(posição, item) substituiremos "Recife" 
        // por “Salvador”;
        int posicaoCidade = cidades.indexOf("Recife");
        cidades.set(posicaoCidade, "Salvador");

        // 8) Agora vamos percorrer a lista novamente, 
        // mas usando Iterator.
        System.out.println("==================");
        System.out.println("Percorrendo a lista usando Iterator:");
        i = 0;
        Iterator<String> iterator = cidades.iterator();
        // o método hasNext() verifica se existe 
        // um próximo elemento para ser iterado
        while (iterator.hasNext()){
            // o método next() retorna o próximo elemento
            System.out.println("Posição " + i + " - " + iterator.next()); 
            i++;
        }
    }
}

Enter fullscreen mode Exit fullscreen mode

A saída após executar a aplicação será:

Percorrendo a lista usando for:
Posição 0 - São Paulo
Posição 1 - Rio de Janeiro
Posição 2 - Recife
Posição 3 - Manaus
Posição 4 - Curitiba
==================
Percorrendo a lista usando for-each:
Posição 0 - Florianópolis
Posição 1 - São Paulo
Posição 2 - Rio de Janeiro
Posição 3 - Recife
Posição 4 - Curitiba
==================
Percorrendo a lista usando Iterator:
Posição 0 - Florianópolis
Posição 1 - São Paulo
Posição 2 - Rio de Janeiro
Posição 3 - Salvador
Posição 4 - Curitiba

Enter fullscreen mode Exit fullscreen mode

Vantagens e Desvantagens do ArrayList

O uso do ArayList é mais indicado quando queremos apenas adicionar elementos em uma lista para posteriormente fazer a iteração. Adicionar elementos ao final de uma lista é bastante simples (isso caso a capacidade de armazenamento do array não tenha sido ultrapassado). O acesso a qualquer elemento do array pelo seu índice também é feito de forma bastante eficiente, ou seja, quando usamos o método get(posição), o tempo para acessar um elemento que esteja no início, ou no meio, ou no fim é praticamente o mesmo, independente do tamanho do vetor.

No entanto, o ArrayList na verdade usa o array padrão internamente, ou seja, quando a capacidade do array acaba, ele precisa criar um novo array com capacidade maior e copiar os elementos do antigo para o novo.

Quando usamos, por exemplo, o método add(posição, item) para adicionar um elemento no início ou no meio do vetor, primeiramente será necessário deslocar cada elemento uma posição para a direita, fazendo com que a posição desejada seja liberada, e só assim adicionar o novo item nesta posição. Caso o array seja muito grande, isso pode consumir muita memória.

Remover elementos no meio ou no início de um array também pode ser muito crítico, pois não é permitido existir “buracos” no vetor, sendo necessário deslocar todos os elementos para a esquerda.

Considerações Finais

Neste artigo foram abordadas algumas características do ArrayList. Vimos que esta classe implementa a interface List e faz parte do pacote java.util. Também conhecemos alguns dos seus métodos mais utilizados e entendemos um pouco do seu funcionamento, bem como suas vantagens e desvantagens.

Dependendo do contexto, talvez outras implementações sejam mais apropriadas, como LinkedList (que também implementa a interface List), ou HashSet (que implementa a interface Set). Mas isso é assunto para um próximo artigo.

Top comments (0)