Java/ArrayList: diferenças entre revisões

Origem: Wikilivros, livros abertos por um mundo aberto.
[edição não verificada][edição não verificada]
Conteúdo apagado Conteúdo adicionado
Sem resumo de edição
Linha 1: Linha 1:
A classe ArrayList é uma implementação da interface List que utiliza um vetor para armazenar elementos. Uma vez que vetores tem tamanho fixo em Java, a classe ArrayList se encarrega de criar um novo vetor (internamente) com um tamanho maior e copiar seus elementos correntes sempre que for necessário.
A classe <code>ArrayList</code> é uma implementação da interface <code>List</code> que utiliza um [[Java/Vetores|vetor]] para armazenar elementos. Uma vez que vetores tem tamanho fixo em Java, a classe <code>ArrayList</code> se encarrega de criar um novo vetor (internamente) com um tamanho maior e copiar seus elementos correntes para esse novo vetor sempre que for necessário.


O vetor interno da classe ArrayList é recriado quando há remoções de elemento, adições de elemento no fim da lista além da capacidade dimensionada e adições de elementos que não no final da lista.
O vetor interno da classe <code>ArrayList</code> é recriado quando há remoções de elemento, adições de elemento no fim da lista além da capacidade dimensionada e adições de elementos que não no final da lista.


Como a operação de recriação do vetor é custosa, busque dimensionar previamente o tamanho da lista, para tal, utilize o construtor sobrecarregado ArrayList(int) enviando como argumento a capacidade inicial da lista. A capacidade inicial padrão de um objeto ArrayList é de 10 elementos.
Como a operação de recriação do vetor é custosa, busque dimensionar previamente o tamanho da lista, para tal, utilize o construtor sobrecarregado <code>ArrayList(int)</code> enviando como argumento a capacidade inicial da lista. A capacidade inicial padrão de um objeto <code>ArrayList</code> é de 10 elementos.


== Performance ==
== Performance ==
Linha 64: Linha 64:
}
}
</source>
</source>
Saída
'''Saída'''
Lista Original [Google Chrome, Mozilla Firefox, Microsoft Internet Explorer]
Lista Original [Google Chrome, Mozilla Firefox, Microsoft Internet Explorer]
Lista Clonada [Google Chrome, Mozilla Firefox, Microsoft Internet Explorer]
Lista Clonada [Google Chrome, Mozilla Firefox, Microsoft Internet Explorer]
Linha 73: Linha 73:
Lista Clonada [Google Chrome, Microsoft Edge]
Lista Clonada [Google Chrome, Microsoft Edge]


Foi utilizado o construtor sobrecarregado '''ArrayList<>(int)''' para definir a capacidade inicial do vetor interno. Não confunda a capacidade inicial do vetor com o tamanho da Lista. O tamanho é devolvido pelo método size() e corresponde à quantidade de elementos armazenados já a capacidade é o tamanho do vetor interno o qual não temos acesso.
Foi utilizado o construtor sobrecarregado <code>ArrayList<>(int)</code> para definir a capacidade inicial do vetor interno. Não confunda a capacidade inicial do vetor com o tamanho da Lista. O tamanho é devolvido pelo método <code>size()</code> e corresponde à quantidade de elementos armazenados já a capacidade é o tamanho do vetor interno o qual não temos acesso.


O método '''ensureCapacity(int)''' recriou o vetor interno com o capacidade para 15 elementos.
O método <code>ensureCapacity(int)</code> recriou o vetor interno com o capacidade para 15 elementos.


O método '''trimToSize(int)''' recriou novamente o vetor interno, porém agora com a capacidade igual ao tamanho da lista, no caso 3.
O método <code>trimToSize(int)</code> recriou novamente o vetor interno, porém agora com a capacidade igual ao tamanho da lista, no caso 3.


O método '''clone()''' atribuiu uma instância de ArrayList à variável listaClone com os mesmos elementos, que são as referências às 3 instâncias do objeto NavegadorWeb que incluímos na variável listaOriginal. Como o método clone() devolve um tipo Object, foi necessário o uso do cast <span class="br0">(</span>ArrayList<span class="sy0"><</span>NavegadorWeb<span class="sy0">></span><span class="br0">). Conforme evidenciado na chamada do método setNome("Edge") o método clone() apenas copia a lista e não cada um de seus elementos e com a chamada ao método remove(1) percebemos que as instâncias de ArrayList nas variáveis listaOriginal e listaClone são diferentes e portanto desvinculadas.</span>
O método <code>clone()</code>, sobrescrito de <code>[[java/Object | Object]]</code> e indicado pela implementação da interface <code>[[java/Clonable | Clonable]]</code>, atribuiu uma instância de <code>ArrayList</code> à variável <code>listaClone</code> com os mesmos elementos, que são as referências às 3 instâncias do objeto <code>NavegadorWeb</code> que incluímos na variável <code>listaOriginal</code>. Como o método <code>clone()</code> devolve um tipo <code>Object</code>, foi necessário o uso do ''cast'' com o tipo <code>(ArrayList<Navegador>)</code>. Conforme evidenciado na chamada do método <code>setNome("Edge")</code> o método <code>clone()</code> apenas copia a lista e não cada um de seus elementos e com a chamada ao método <code>remove(1)</code> percebemos que as instâncias de <code>ArrayList</code> nas variáveis <code>listaOriginal</code> e <code>listaClone</code> são diferentes e portanto desvinculadas.


Como você pode ter concluído, o uso dos métodos ensureCapacity(int) e trimToSize(int) não é recomendável pois ele recria o vetor interno do objeto ArrayList o que prejudica a performance.
Como você pode ter concluído, o uso dos métodos <code>ensureCapacity(int)</code> e <code>trimToSize(int)</code> não é recomendável pois eles recriam o vetor interno do objeto <code>ArrayList</code> situação em que a performance é prejudicada.


= Exercício =
= Exercício =
# Depure o código acima e observe em que chamadas de métodos o atributo elementData é alterado.
# Depure o código acima e observe em que chamadas de métodos o atributo elementData é alterado.
# Os métodos add() e remove() alteram a capacidade da instância de ArrayList das variáveis listaOriginal e listaClone?
# Os métodos <code>add()</code> e <code>remove()</code> alteram a capacidade da instância de <code>ArrayList</code> das variáveis <code>listaOriginal</code> e <code>listaClone</code>?

Revisão das 22h32min de 27 de junho de 2016

A classe ArrayList é uma implementação da interface List que utiliza um vetor para armazenar elementos. Uma vez que vetores tem tamanho fixo em Java, a classe ArrayList se encarrega de criar um novo vetor (internamente) com um tamanho maior e copiar seus elementos correntes para esse novo vetor sempre que for necessário.

O vetor interno da classe ArrayList é recriado quando há remoções de elemento, adições de elemento no fim da lista além da capacidade dimensionada e adições de elementos que não no final da lista.

Como a operação de recriação do vetor é custosa, busque dimensionar previamente o tamanho da lista, para tal, utilize o construtor sobrecarregado ArrayList(int) enviando como argumento a capacidade inicial da lista. A capacidade inicial padrão de um objeto ArrayList é de 10 elementos.

Performance

Métodos não constantes na interface List

package livro_java.colecoes.listas;

import java.util.ArrayList;

public class UtilizandoArrayList {

    public static void main(String[] args) {

        ArrayList<NavegadorWeb> listaOriginal = new ArrayList<>(2);
        ArrayList<NavegadorWeb> listaClone;
        
        listaOriginal.ensureCapacity(15);
        
        listaOriginal.add(new NavegadorWeb("Chrome", "Google"));
        listaOriginal.add(new NavegadorWeb("Firefox", "Mozilla"));
        listaOriginal.add(new NavegadorWeb("Microsoft", "Internet Explorer"));

        listaOriginal.trimToSize();

        listaClone = (ArrayList<NavegadorWeb>) listaOriginal.clone();

        System.out.printf("%-20s %s%n", "Lista Original", listaOriginal);
        System.out.printf("%-20s %s%n", "Lista Clonada", listaClone);

        listaClone.get(2).setNome("Edge");
        listaClone.remove(1);

        System.out.println("\nApós alteração\n");
        System.out.printf("%-20s %s%n", "Lista Original", listaOriginal);
        System.out.printf("%-20s %s%n", "Lista Clonada", listaClone);

    }
}

class NavegadorWeb {
    private String nome;
    private String empresa;

    NavegadorWeb(String nome, String empresa) {
        this.nome = nome;
        this.empresa = empresa;
    }

    public void setNome(String nome) {
        this.nome = nome;
    }

    @Override
    public String toString() {
        return empresa + " " + nome;
    }
}

Saída

Lista Original       [Google Chrome, Mozilla Firefox, Microsoft Internet Explorer]
Lista Clonada        [Google Chrome, Mozilla Firefox, Microsoft Internet Explorer]

Após alteração

Lista Original       [Google Chrome, Mozilla Firefox, Microsoft Edge]
Lista Clonada        [Google Chrome, Microsoft Edge]

Foi utilizado o construtor sobrecarregado ArrayList<>(int) para definir a capacidade inicial do vetor interno. Não confunda a capacidade inicial do vetor com o tamanho da Lista. O tamanho é devolvido pelo método size() e corresponde à quantidade de elementos armazenados já a capacidade é o tamanho do vetor interno o qual não temos acesso.

O método ensureCapacity(int) recriou o vetor interno com o capacidade para 15 elementos.

O método trimToSize(int) recriou novamente o vetor interno, porém agora com a capacidade igual ao tamanho da lista, no caso 3.

O método clone(), sobrescrito de Object e indicado pela implementação da interface Clonable, atribuiu uma instância de ArrayList à variável listaClone com os mesmos elementos, que são as referências às 3 instâncias do objeto NavegadorWeb que incluímos na variável listaOriginal. Como o método clone() devolve um tipo Object, foi necessário o uso do cast com o tipo (ArrayList<Navegador>). Conforme evidenciado na chamada do método setNome("Edge") o método clone() apenas copia a lista e não cada um de seus elementos e com a chamada ao método remove(1) percebemos que as instâncias de ArrayList nas variáveis listaOriginal e listaClone são diferentes e portanto desvinculadas.

Como você pode ter concluído, o uso dos métodos ensureCapacity(int) e trimToSize(int) não é recomendável pois eles recriam o vetor interno do objeto ArrayList situação em que a performance é prejudicada.

Exercício

  1. Depure o código acima e observe em que chamadas de métodos o atributo elementData é alterado.
  2. Os métodos add() e remove() alteram a capacidade da instância de ArrayList das variáveis listaOriginal e listaClone?