CodeGym /Blogue Java /Random-PT /Java ArrayList
John Squirrels
Nível 41
San Francisco

Java ArrayList

Publicado no grupo Random-PT
Oi! Nas lições anteriores, nos aprofundamos nos arrays e revisamos exemplos comuns de como trabalhar com arrays. Nesta lição, faremos uma revisão mais detalhada do Java ArrayList. Em geral, arrays são super úteis. E, como você já percebeu, você pode fazer muito com eles :) Mas os arrays têm uma série de deficiências.
  • Tamanho limitado. Você precisa saber quantos elementos seu array precisa conter no momento de criá-lo. Se você subestimar, não terá espaço suficiente. Superestime e a matriz permanecerá meio vazia, o que também é ruim. Afinal, você ainda está alocando mais memória do que o necessário.

  • Uma matriz não possui métodos para adicionar elementos. Você sempre deve indicar explicitamente o índice da posição onde deseja adicionar um elemento. Se você especificar acidentalmente o índice para uma posição ocupada por algum valor necessário, ele será substituído.

  • Não há métodos para excluir um item. Um valor só pode ser "zerado".

public class Cat {

   private String name;

   public Cat(String name) {
       this.name = name;
   }

   public static void main(String[] args) {

       Cat[] cats = new Cat[3];
       cats[0] = new Cat("Thomas");
       cats[1] = new Cat("Behemoth");
       cats[2] = new Cat("Lionel Messi");

       cats[1] = null;

      
      
       System.out.println(Arrays.toString(cats));
   }

   @Override
   public String toString() {
       return "Cat{" +
               "name='" + name + '\'' +
               '}';
   }
}
Saída: [Cat{name='Thomas'}, null, Cat{name='Lionel Messi'}] Felizmente, os criadores de Java estão bem cientes das vantagens e desvantagens dos arrays e, portanto, criaram uma estrutura de dados muito interessante chamada Java ArrayList . Falando da maneira mais simples possível, um Java ArrayList é um array "enriquecido" com muitos recursos novos.

Como criar um ArrayList

É muito fácil criar:

ArrayList<Cat> cats = new ArrayList<Cat>();
Agora criamos uma lista para armazenar objetos Cat . Observe que não estamos especificando o tamanho do ArrayList , porque ele pode expandir automaticamente. Como isso é possível? É bem simples, na verdade. Você pode se surpreender, mas o ArrayList em Java é construído sobre um array muito comum :) Sim, ele contém um array, e é onde nossos elementos são armazenados. Mas ArrayList em Java tem uma maneira especial de trabalhar com esse array:
  • Quando o array interno é preenchido, ArrayList cria um novo array internamente. O tamanho da nova matriz é o tamanho da matriz antiga vezes 1,5 mais 1.

  • Todos os dados são copiados do array antigo para o novo

  • A matriz antiga é limpa pelo coletor de lixo.
Esse mecanismo permite que o Java ArrayList (ao contrário de um array comum) implemente um método para adicionar novos elementos. é o add()método

public static void main(String[] args) {

   ArrayList<Cat> cats = new ArrayList<Cat>();
   cats.add(new Cat("Behemoth"));
}
Novos itens são adicionados ao final da lista. Agora não há risco de estourar o array, então esse método é totalmente seguro. A propósito, ArrayList pode não apenas encontrar um objeto por seu índice, mas também vice-versa: ele pode usar uma referência para encontrar o índice de um objeto no ArrayList ! É para isso que serve o método indexOf() : Passamos uma referência ao objeto que queremos e indexOf() retorna seu índice:

public static void main(String[] args) {

   ArrayList<Cat> cats = new ArrayList<>();
   Cat thomas = new Cat("Thomas");
   Cat behemoth = new Cat("Behemoth");
   Cat lionel = new Cat("Lionel Messi");
   Cat fluffy = new Cat ("Fluffy");

   cats.add(thomas);
   cats.add(behemoth);
   cats.add(lionel);
   cats.add(fluffy);

   int thomasIndex = cats.indexOf(thomas);
   System.out.println(thomasIndex);
}
Saída: 0 Isso mesmo. Nosso objeto thomas é de fato armazenado no elemento 0. Arrays não têm apenas desvantagens. Eles também têm vantagens inquestionáveis. Uma delas é a capacidade de pesquisar elementos por índice. Como apontamos para um índice, ou seja, para um endereço de memória específico, pesquisar um array dessa maneira é muito rápido. ArrayListtambém sabe fazer! O método get() implementa isso:

public static void main(String[] args) {

   ArrayList<Cat> cats = new ArrayList<>();
   Cat thomas = new Cat("Thomas");
   Cat behemoth = new Cat("Behemoth");
   Cat lionel = new Cat("Lionel Messi");
   Cat fluffy = new Cat ("Fluffy");

   cats.add(thomas);
   cats.add(behemoth);
   cats.add(lionel);
   cats.add(fluffy);

   Cat secondCat = cats.get(1);

   System.out.println(secondCat);
}
Saída: Cat{name='Behemoth'} Além disso, você pode descobrir facilmente se o ArrayList contém um objeto específico. Isso é feito usando o método ArrayList contains():

public static void main(String[] args) {

   ArrayList<Cat> cats = new ArrayList<>();
   Cat thomas = new Cat("Thomas");
   Cat behemoth = new Cat("Behemoth");
   Cat lionel = new Cat("Lionel Messi");
   Cat fluffy = new Cat ("Fluffy");

   cats.add(thomas);
   cats.add(behemoth);
   cats.add(lionel);
   cats.add(fluffy);

   cats.remove(fluffy);
   System.out.println(cats.contains(fluffy));
}
O método verifica se o array interno de ArrayList contém o elemento e retorna um valor booleano (verdadeiro ou falso). Saída: false E outra coisa importante sobre a inserção. ArrayList permite que você use um índice para inserir elementos não apenas no final da matriz, mas em qualquer lugar. Ele tem dois métodos para isso:
  • ArrayList add(índice int, elemento Cat)
  • ArrayList set(índice int, elemento Cat)
Como argumentos, ambos os métodos recebem o índice da posição onde você deseja inserir e uma referência ao próprio objeto. A diferença é que inserir usando set() sobrescreve o valor antigo. Inserir usando add() primeiro desloca todos os elementos de [index] para o final da matriz e, em seguida, adiciona o objeto especificado na posição vazia resultante.

Aqui está um exemplo:


public static void main(String[] args) {

   ArrayList<Cat> cats = new ArrayList<>();
   Cat thomas = new Cat("Thomas");
   Cat behemoth = new Cat("Behemoth");
   Cat lionel = new Cat("Lionel Messi");
   Cat fluffy = new Cat ("Fluffy");

   cats.add(thomas);
   cats.add(behemoth);

   System.out.println(cats.toString());

   cats.set(0, lionel);// Now we have a list of 2 cats. Adding a 3rd using set

   System.out.println(cats.toString());
}
Resultado: [[Cat{name='Thomas'}, Cat{name='Behemoth'}] [Cat{name='Lionel Messi'}, Cat{name='Behemoth'}] Tínhamos uma lista de 2 gatos . Então inserimos outro como elemento 0 usando o método set() . Como resultado, o elemento antigo foi substituído por um novo.

public static void main(String[] args) {

   ArrayList<Cat> cats = new ArrayList<>();
   Cat thomas = new Cat("Thomas");
   Cat behemoth = new Cat("Behemoth");
   Cat lionel = new Cat("Lionel Messi");
   Cat fluffy = new Cat ("Fluffy");

   cats.add(thomas);
   cats.add(behemoth);

   System.out.println(cats.toString());

   cats.add(0, lionel);// Now we have a list of 2 cats. Adding a 3rd using add

   System.out.println(cats.toString());
}
E aqui vemos que add() funciona de forma diferente. Ele move todos os elementos para a direita e então escreve o novo valor como elemento 0. Saída: [Cat{name='Thomas'}, Cat{name='Behemoth'}] [Cat{name='Lionel Messi'}, Cat{name='Thomas'}, Cat{name='Behemoth'}] Para limpar completamente a lista, usamos o método clear() :

public static void main(String[] args) {

   ArrayList<Cat> cats = new ArrayList<>();
   Cat thomas = new Cat("Thomas");
   Cat behemoth = new Cat("Behemoth");
   Cat lionel = new Cat("Lionel Messi");
   Cat fluffy = new Cat ("Fluffy");

   cats.add(thomas);
   cats.add(behemoth);
   cats.add(lionel);
   cats.add(fluffy);

   cats.clear();

   System.out.println(cats.toString());
}
Saída: [] Tudo foi removido da lista. A propósito, observe: ao contrário dos arrays, ArrayList substitui o método toString() e já exibe a lista apropriadamente como strings. Com arrays comuns, tivemos que usar a classe Arrays para isso. E já que mencionei Arrays : Java permite que você "alterne" facilmente entre um array e um ArrayList , ou seja, converta um em outro. A classe Arrays tem um método Arrays.asList() para isso. Nós o usamos para obter o conteúdo como um array e passá-lo para nosso construtor ArrayList :

public static void main(String[] args) {

   ArrayList<Cat> cats = new ArrayList<>();


   Cat thomas = new Cat("Thomas");
   Cat behemoth = new Cat("Behemoth");
   Cat lionel = new Cat("Lionel Messi");
   Cat fluffy = new Cat ("Fluffy");

   Cat[] catsArray = {thomas, behemoth, lionel, fluffy};

   ArrayList<Cat> catsList = new ArrayList<>(Arrays.asList(catsArray));
   System.out.println(catsList);
}
Saída: [Cat{name='Thomas'}, Cat{name='Behemoth'}, Cat{name='Lionel Messi'}, Cat{name='Fluffy'}] Você também pode ir na direção oposta: get uma matriz de um objeto ArrayList . Fazemos isso usando o método toArray() :

public static void main(String[] args) {

   ArrayList<Cat> cats = new ArrayList<>();

   Cat thomas = new Cat("Thomas");
   Cat behemoth = new Cat("Behemoth");
   Cat lionel = new Cat("Lionel Messi");
   Cat fluffy = new Cat ("Fluffy");

   cats.add(thomas);
   cats.add(behemoth);
   cats.add(lionel);
   cats.add(fluffy);

   Cat[] catsArray = cats.toArray(new Cat[0]);

   System.out.println(Arrays.toString(catsArray));
}
Observação: passamos um array vazio para o método toArray() . Isso não é um erro. Dentro da classe ArrayList , esse método é implementado de forma que passar um array vazio aumenta seu desempenho. Apenas tenha isso em mente para o futuro (claro, você pode passar um array de algum tamanho específico; isso também funcionará). Oh, sobre o tamanho. O tamanho atual da lista pode ser encontrado usando o método size() :

public static void main(String[] args) {

   ArrayList<Cat> cats = new ArrayList<>();


   Cat thomas = new Cat("Thomas");
   Cat behemoth = new Cat("Behemoth");
   Cat lionel = new Cat("Lionel Messi");
   Cat fluffy = new Cat ("Fluffy");

   cats.add(thomas);
   cats.add(behemoth);
   cats.add(lionel);
   cats.add(fluffy);

   System.out.println(cats.size());
}
É importante entender que, ao contrário da propriedade length de um array , o método ArrayList.size() retorna o número real de elementos, não a capacidade original. Afinal, não especificamos um tamanho ao criar o ArrayList . No entanto, você pode especificá-lo — ArrayList tem um construtor adequado. Mas em termos de adicionar novos elementos, isso não muda seu comportamento:

public static void main(String[] args) {

   ArrayList<Cat> cats = new ArrayList<>(2);// create an ArrayList with an initial capacity of 2


   Cat thomas = new Cat("Thomas");
   Cat behemoth = new Cat("Behemoth");
   Cat lionel = new Cat("Lionel Messi");
   Cat fluffy = new Cat ("Fluffy");

   cats.add(thomas);
   cats.add(behemoth);
   cats.add(lionel);
   cats.add(fluffy);

   System.out.println(cats.size());
}
Saída do console: 4 Criamos uma lista de 2 elementos, mas ela se expandiu discretamente quando precisávamos. Outra consideração é que se criarmos uma lista muito pequena inicialmente, ela terá que expandir com mais frequência, o que consumirá alguns recursos. Quase não tocamos no processo de remoção de elementos de um ArrayList nesta lição. Claro, isso não é porque nos esquecemos. Colocamos este tópico em uma lição separada que você conhecerá mais tarde :) Para reforçar o que você aprendeu, sugerimos que você assista a uma vídeo aula do nosso Curso de Java
Comentários
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION