JavaRush /Blogue Java /Random-PT /Classe ArrayList em Java

Classe ArrayList em Java

Publicado no grupo Random-PT
Olá! Nas palestras anteriores, examinamos detalhadamente uma estrutura de dados como um array e examinamos exemplos comuns de como trabalhar com eles. Mas esta estrutura de dados tem uma série de desvantagens. A resposta para eles em Java foi o aparecimento de ArrayList. Para simplificar o máximo possível, um ArrayList em Java é um array “atualizado” com muitos recursos novos.Classe ArrayList - 1

Como o Java Arraylist é diferente dos arrays regulares?

Em geral, os arrays são bastante convenientes e, como você já notou, você pode fazer muitas coisas com eles :) No entanto, os arrays também apresentam uma série de desvantagens.
  • Tamanho limitado. Você já precisa saber na fase de criação de um array quantas células ele deve conter. Se você subestimar a quantidade necessária, não haverá espaço suficiente. Se você superestimar, o array permanecerá meio vazio, e isso não é tão ruim. Afinal, você também alocará mais memória do que o necessário.
  • Um array não possui métodos para adicionar elementos. Você sempre deve especificar explicitamente o índice da célula onde deseja adicionar o elemento. Se você especificar acidentalmente uma célula já ocupada com algum valor desejado, ela será substituída.
  • Não existem métodos para remover um elemento. O 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("Hippopotamus");
       cats[2] = new Cat("Philip Markovich");

       cats[1] = null;



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

   @Override
   public String toString() {
       return "Cat{" +
               "name='" + name + '\'' +
               '}';
   }
}
Conclusão:

[Cat{name='Томас'}, null, Cat{name='Фorпп Маркович'}]
Todas essas deficiências podem ser eliminadas usando ArrayList. É criado de forma muito simples:
ArrayList<Cat> cats = new ArrayList<Cat>();
Agora criamos uma lista para armazenar objetos Cat. Prestar atenção:não especificamos o tamanho do ArrayList porque ele é automaticamente expansível. Como isso é possível? Facilmente. Você ficará surpreso, mas ArrayList é baseado em um array comum :) Sim, dentro dele existe um array no qual nossos elementos são armazenados. Mas ArrayList possui um mecanismo especial para trabalhar com ele:
  • Quando este array interno está cheio, o ArrayList cria um novo array dentro de si. Seu tamanho = (tamanho do array antigo * 1,5) +1.
  • Todos os dados são copiados do array antigo para o novo
  • A matriz antiga é removida pelo coletor de lixo.
Graças a este mecanismo, um ArrayList (em oposição a um array) implementa um método para adicionar um novo elemento. Este é um método add().
public static void main(String[] args) {

   ArrayList<Cat> cats = new ArrayList<Cat>();
   cats.add(new Cat("Hippopotamus"));
}
O novo elemento é adicionado ao final da lista. Agora não há risco de transbordamento, portanto este mecanismo é totalmente seguro. A propósito, ArrayList pode não apenas procurar um objeto por índice, mas também vice-versa - ele pode encontrar o índice de um objeto em ArrayList por referência ao objeto! Para fazer isso, ele implementa o método indexOf(): Passamos nele um link para o objeto desejado, e indexOf()ele nos retorna seu índice:
public static void main(String[] args) {

   ArrayList<Cat> cats = new ArrayList<>();
   Cat thomas = new Cat("Thomas");
   Cat behemoth = new Cat("Hippopotamus");
   Cat philipp = new Cat("Philip Markovich");
   Cat pushok = new Cat("Fluff");

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

   int thomasIndex = cats.indexOf(thomas);
   System.out.println(thomasIndex);
}
Conclusão:

0
Isso mesmo, o objeto thomasestá realmente armazenado na célula 0. As matrizes não têm apenas desvantagens, mas também vantagens indiscutíveis. Um deles é procurar um elemento por índice. Como apontamos para um índice, ou seja, para um endereço específico na memória, essa busca no array é muito rápida. ArrayList em Java também pode fazer isso! Para fazer isso, ele implementa um método get():
public static void main(String[] args) {

   ArrayList<Cat> cats = new ArrayList<>();
   Cat thomas = new Cat("Thomas");
   Cat behemoth = new Cat("Hippopotamus");
   Cat philipp = new Cat("Philip Markovich");
   Cat pushok = new Cat("Fluff");

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

   Cat secondCat = cats.get(1);

   System.out.println(secondCat);
}
Conclusão:

Cat{name='Бегемот'}
Além disso, você pode descobrir facilmente se um ArrayList contém um objeto específico ou não. Isso é feito usando o método contains():
public static void main(String[] args) {

   ArrayList<Cat> cats = new ArrayList<>();
   Cat thomas = new Cat("Thomas");
   Cat behemoth = new Cat("Hippopotamus");
   Cat philipp = new Cat("Philip Markovich");
   Cat pushok = new Cat("Fluff");

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

   cats.remove(pushok);
   System.out.println(cats.contains(pushok));
}
O método verifica se o elemento está contido no array interno do ArrayList e retorna o resultado no formato boolean- trueou false. Conclusão:

false
E outra coisa importante sobre a inserção. ArrayList permite inserir dados não apenas no final do array, mas também em qualquer célula por índice. Possui dois métodos para isso:
  • add(int index, Cat element)
  • set(int index, Cat element)
Para ambos, você passa o índice da célula na qual deseja inserir e um link para o próprio objeto. A diferença é que colar set()substitui o valor antigo armazenado na célula. E inserir add()primeiro desloca todos os elementos [index]do array até o final e adiciona o objeto necessário à célula 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("Hippopotamus");
   Cat philipp = new Cat("Philip Markovich");
   Cat pushok = new Cat("Fluff");

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

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

   cats.set(0, philipp);//Now we have a list of 2 cats. We add the 3rd via set:

   System.out.println(cats.toString());
}
Conclusão:

[[Cat{name='Томас'}, Cat{name='Бегемот'}]
[Cat{name='Фorпп Маркович'}, Cat{name='Бегемот'}]
Tínhamos uma lista de 2 gatos, inserimos outro através do método set()na célula 0. Como resultado, o valor antigo armazenado nesta célula 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("Hippopotamus");
   Cat philipp = new Cat("Philip Markovich");
   Cat pushok = new Cat("Fluff");

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

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

   cats.add(0, philipp);//Now we have a list of 2 cats. Add the 3rd via add

   System.out.println(cats.toString());
}
Mas add()funcionou de forma diferente. Ele deslocou todos os elementos para a direita e escreveu o novo valor na célula 0. Conclusão:

[Cat{name='Томас'}, Cat{name='Бегемот'}]
[Cat{name='Фorпп Маркович'}, Cat{name='Томас'}, Cat{name='Бегемот'}]
Para limpar completamente a lista, use o método clear():
public static void main(String[] args) {

   ArrayList<Cat> cats = new ArrayList<>();
   Cat thomas = new Cat("Thomas");
   Cat behemoth = new Cat("Hippopotamus");
   Cat philipp = new Cat("Philip Markovich");
   Cat pushok = new Cat("Fluff");

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

   cats.clear();

   System.out.println(cats.toString());
}
Conclusão:

[]
Todo o conteúdo foi removido da lista. A propósito, preste atenção: diferentemente dos arrays, em ArrayList o método toString() é sobrescrito e exibe imediatamente a lista em formato de string. No caso de arrays, tivemos que utilizar a classe Arrays para isso. E já que lembramos de Arrays: em Java você pode facilmente “alternar” entre um array e um ArrayList, ou seja, converter um no outro. A classe Arrays possui um método para isso, Arrays.asList(). Com sua ajuda, obtemos o conteúdo do array como uma lista e o passamos para o construtor do nosso ArrayList:
public static void main(String[] args) {

   Cat thomas = new Cat("Thomas");
   Cat behemoth = new Cat("Hippopotamus");
   Cat philipp = new Cat("Philip Markovich");
   Cat pushok = new Cat("Fluff");

   Cat[] catsArray = {thomas, behemoth, philipp, pushok};

   ArrayList<Cat> catsList = new ArrayList<>(Arrays.asList(catsArray));
   System.out.println(catsList);
}
Conclusão:

[Cat{name='Томас'}, Cat{name='Бегемот'}, Cat{name='Фorпп Маркович'}, Cat{name='Пушок'}]
Você pode fazer o oposto - obter um array de um objeto ArrayList. Para fazer isso, use o método toArray():
public static void main(String[] args) {

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

   Cat thomas = new Cat("Thomas");
   Cat behemoth = new Cat("Hippopotamus");
   Cat philipp = new Cat("Philip Markovich");
   Cat pushok = new Cat("Fluff");

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

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

   System.out.println(Arrays.toString(catsArray));
}
Observação: passamos um array vazio para o método toArray(). Não é um erro. Dentro da classe ArrayList, este método é implementado de forma que passar um array vazio aumenta seu desempenho. Por enquanto, lembre-se disso para o futuro (mas você também pode transferir um tamanho específico, vai funcionar). Falando em 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("Hippopotamus");
   Cat philipp = new Cat("Philip Markovich");
   Cat pushok = new Cat("Fluff");

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

   System.out.println(cats.size());
}
É importante entender aqui que, diferentemente da lengthpropriedade array, o método ArrayList.size() retorna exatamente o número de elementos, e não a capacidade inicial, pois não a especificamos ao criar o ArrayList. Aliás, geralmente é possível indicá-lo. ArrayList possui um construtor correspondente. Mas o seu comportamento em termos de adição de novos elementos não mudará:
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("Hippopotamus");
   Cat philipp = new Cat("Philip Markovich");
   Cat pushok = new Cat("Fluff");

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

   System.out.println(cats.size());
}
Saída do console:

4
Criamos uma lista com 2 elementos, mas quando precisávamos ela expandia facilmente. Outra coisa é que se inicialmente criamos uma lista muito pequena, ela terá que realizar a operação de expansão com mais frequência, e isso consome uma certa quantidade de recursos. Nesta palestra, mal tocamos no processo de remoção de elementos de um ArrayList. Claro, isso não se deve ao esquecimento. Este tópico foi separado em uma palestra separada, que você pode ler mais :)
Comentários
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION