Dúvidas com ArrayList

9 respostas
R

Colegas,

Estou começando a programar em java e estou com algumas dificuldades em relação a trabalhar com ArrayList e se possível gostaria que vocês me ajudassem. Procurei no fórum mas não achei uma resposta para a minha dúvida.
Criei alguns objetos específicos para a minha aplicação. Ela vai acessar duas bases de dados distintas buscando informações e realizando comparações entre elas. Para isso criei dois arrays:

List<objeto1> lista1 = new ArrayList(); //lista1 vai buscar informação na base 1
List<objeto1> lista2 = new ArrayList(); //lista2 vai buscar informação na base 2
// as listas 1 e 2 são do mesmo tipo de objeto
// estou utilizando List<objeto> porque facilita minha vida em outro ponto do código

Gostaria de fazer uma comparação inicial para verificar se as duas listas são iguais. Tentei

boolean resultado = java.util.Arrays.equals(lista1,lista2);

Mas o java reclama dizendo que os tipos boolean e java.util.Arrays.equals são incompatíveis, mas a documentação diz que esse método retorna um boolean e o programa não compila. O que estou fazendo de errado?

Em seguida, gostaria de fazer um “diff” entre os dois arrays, pegando as diferenças entre eles. Estou percorrendo um deles e vou “perguntando” para o outro se o elemento está presente. Mas para isso funcionar, tenho que percorrer o primeiro perguntando para o segundo e vice-versa para conseguir capturar todas as diferenças e depois trabalhar com elas. Isso está funcionando, mas to achando meio “porco”. Tem algum método “mais elegante” para fazer isso?

Obrigado pela ajuda.

9 Respostas

T

Para comparar dois ArrayList, você usa o próprio método equals:

if (lista1.equals (lista2))

Só que o problema, obviamente, é definir corretamente o método equals na classe objeto1.

F

É, e a sobrescrição do método equals() é fundamental para você determinar quando os dois objetos devem ser considerados como iguais.

ignacio83

Para obter a difereça os elementos diferentes vc pode fazer assim:

lista1.removeAll(lista2);

Na lista1 vai sobrar somente os elementos diferentes… Mas assim como disse o fernandoeick, vc terá que implementar o equals da classe dos elementos da lista.

T

Hum… agora vi: a comparação que dá para fazer usando diretamente “equals” só serve se os arraylists forem exatamente iguais. Se os dados forem iguais, mas em sequência diferente, então não dá para usar “equals”.
Nesse caso, você pode ordenar os dois arraylists, e a seguir comparar.

Mas o que você quer saber, na verdade, não é algo tão básico como “saber se são iguais ou diferentes”. Você quer uma lista de diferenças; nesse caso, depende um pouco de seus dados. Você pode, em vez de usar um ArrayList, usar um TreeSet, e usar o método removeAll ou retainAll. Rode o programa abaixo e veja o que você quer dizer por “diferença”. (Talvez seja a diferença simples entre conjuntos, e talvez seja a diferença simétrica.)

import java.util.*;

class Cliente {
    private int id;
    private String nome;
    private String endereco;
    public int getId() { return id; } public void setId (int id_) { id = id_; }
    public String getNome() { return nome; } public void setNome (String nome_) { nome = nome_; }
    public String getEndereco() { return endereco; } public void setEndereco (String endereco_) { endereco = endereco_; }
    public Cliente (String nome_, String endereco_, int id_) { id = id_; nome = nome_; endereco = endereco_; }
    public String toString () { return "id=" + id + ",nome=" + nome + ",endereco=" + endereco; }    
}

class ClienteComparator implements Comparator<Cliente> {
    public int compare (Cliente c1, Cliente c2) {
        if (c1.getId() != c2.getId()) return c1.getId() - c2.getId();
        int ret = c1.getNome().compareTo (c2.getNome());
        if (ret != 0) return ret;
        ret = c1.getEndereco().compareTo (c2.getEndereco());
        return ret;
    }
}

class TesteTreeSet {
    // Retorna uma lista dos clientes que estão em clientes1 mas não estão em clientes2
    public static Set<Cliente> diferenca (Set<Cliente> clientes1, Set<Cliente> clientes2) {
        Set<Cliente> ret = new TreeSet<Cliente>(new ClienteComparator());
        ret.addAll (clientes1);
        ret.removeAll (clientes2);
        return ret;
    }
    // Retorna a união das listas clientes1 e clientes2
    public static Set<Cliente> uniao (Set<Cliente> clientes1, Set<Cliente> clientes2) {
        Set<Cliente> ret = new TreeSet<Cliente>(new ClienteComparator());
        ret.addAll (clientes1);
        ret.addAll (clientes2);
        return ret;
    }
    // Retorna uma lista de clientes que estão em clientes1 mas não estão em clientes2, 
    // juntamente com uma lista de clientes que estão em cliente2 mas não estão em clientes1
    public static Set<Cliente> diferencaSimetrica (Set<Cliente> clientes1, Set<Cliente> clientes2) {
        Set<Cliente> dif1 = diferenca (clientes1, clientes2);
        Set<Cliente> dif2 = diferenca (clientes2, clientes1);
        return uniao (dif1, dif2);
    }
    // Retorna a intersecção das listas clientes1 e clientes2
    // (ou seja, os clientes que estão em ambas as listas
    public static Set<Cliente> interseccao (Set<Cliente> clientes1, Set<Cliente> clientes2) {
        Set<Cliente> ret = new TreeSet<Cliente>(new ClienteComparator());
        ret.addAll (clientes1);
        ret.retainAll (clientes2);
        return ret;
    }

    public static void main(String[] args) {
        TreeSet<Cliente> clientes1 = new TreeSet<Cliente>(new ClienteComparator());
        TreeSet<Cliente> clientes2 = new TreeSet<Cliente>(new ClienteComparator());

        clientes1.add (new Cliente ("Jose Aparecido", "R. dos Bobos, 0", 7));
        clientes1.add (new Cliente ("Maria Isabel", "Av. America, 200", 13));
        clientes1.add (new Cliente ("Jesus Madonna", "Beverly Hills, 92010", 17));

        clientes2.add (new Cliente ("Marisa Morro", "Palacio do Crepusculo, 20", 22));
        clientes2.add (new Cliente ("Maria Isabel", "Av. America, 200", 13));
        clientes2.add (new Cliente ("Jesus Madonna", "Beverly Hills, 92010", 17));
        clientes2.add (new Cliente ("Andersen Clayton", "Comunidade da Fazendinha, barraco 777", 99));

        System.out.println ("-- Diferenca clientes1 - clientes2 --");
        System.out.println (diferenca (clientes1, clientes2));
        System.out.println ("-- Diferenca clientes2 - clientes1 --");
        System.out.println (diferenca (clientes2, clientes1));
        System.out.println ("-- Uniao clientes1 U clientes2 --");
        System.out.println (uniao (clientes1, clientes2));
        System.out.println ("-- Diferenca Simetrica clientes1 & clientes2 --");
        System.out.println (diferencaSimetrica (clientes1, clientes2));
        System.out.println ("-- Interseccao clientes1 ^ clientes2 --");
        System.out.println (interseccao (clientes1, clientes2));
    }
}
R

Colegas,

Obrigado pelas sugestões, estava lendo um pouco mais sobre comparação e vi que provavelmente teria que reescrever o “equals”, e as informações que vocês forneceram comprovaram isso.

Thingol, eu estou realmente precisando da diferença simétrica, e o código que você postou parece ser o caminho para a solução do meu problema. Mas de qualquer modo terei que escrever o código para comparar os objetos, não tem como evitar isso.

Uma pergunta, como se dá a performance do TreeSet? É eficiente quando falamos de muitos objetos? Estamos falando de uns 10.000 objetos (5.000 para cada set) a serem comparados.

Novamente, obrigado pelas contribuições!

T

Já que perguntou…

Vou fazer um pequeno benchmark.

T
import java.util.*;

class Cliente {
    private int id;
    private String nome;
    private String endereco;
    public int getId() { return id; } public void setId (int id_) { id = id_; }
    public String getNome() { return nome; } public void setNome (String nome_) { nome = nome_; }
    public String getEndereco() { return endereco; } public void setEndereco (String endereco_) { endereco = endereco_; }
    public Cliente (String nome_, String endereco_, int id_) { id = id_; nome = nome_; endereco = endereco_; }
    public String toString () { return "id=" + id + ",nome=" + nome + ",endereco=" + endereco; }    
}

class ClienteComparator implements Comparator<Cliente> {
    public int compare (Cliente c1, Cliente c2) {
        if (c1.getId() != c2.getId()) return c1.getId() - c2.getId();
        int ret = c1.getNome().compareTo (c2.getNome());
        if (ret != 0) return ret;
        ret = c1.getEndereco().compareTo (c2.getEndereco());
        return ret;
    }
}

class TesteTreeSet {
    // Retorna uma lista dos clientes que estão em clientes1 mas não estão em clientes2
    public static Set<Cliente> diferenca (Set<Cliente> clientes1, Set<Cliente> clientes2) {
        Set<Cliente> ret = new TreeSet<Cliente>(new ClienteComparator());
        ret.addAll (clientes1);
        ret.removeAll (clientes2);
        return ret;
    }
    // Retorna a união das listas clientes1 e clientes2
    public static Set<Cliente> uniao (Set<Cliente> clientes1, Set<Cliente> clientes2) {
        Set<Cliente> ret = new TreeSet<Cliente>(new ClienteComparator());
        ret.addAll (clientes1);
        ret.addAll (clientes2);
        return ret;
    }
    // Retorna uma lista de clientes que estão em clientes1 mas não estão em clientes2, 
    // juntamente com uma lista de clientes que estão em cliente2 mas não estão em clientes1
    public static Set<Cliente> diferencaSimetrica (Set<Cliente> clientes1, Set<Cliente> clientes2) {
        Set<Cliente> dif1 = diferenca (clientes1, clientes2);
        Set<Cliente> dif2 = diferenca (clientes2, clientes1);
        return uniao (dif1, dif2);
    }
    // Retorna a intersecção das listas clientes1 e clientes2
    // (ou seja, os clientes que estão em ambas as listas
    public static Set<Cliente> interseccao (Set<Cliente> clientes1, Set<Cliente> clientes2) {
        Set<Cliente> ret = new TreeSet<Cliente>(new ClienteComparator());
        ret.addAll (clientes1);
        ret.retainAll (clientes2);
        return ret;
    }

    public static void main(String[] args) {
        TreeSet<Cliente> clientes1 = new TreeSet<Cliente>(new ClienteComparator());
        TreeSet<Cliente> clientes2 = new TreeSet<Cliente>(new ClienteComparator());

        for (int i = 0; i < 5000; i++) 
            clientes1.add (new Cliente ("nome " + i, "endereco " + i, i));
        for (int i = 2500; i < 7500; i++) 
            clientes2.add (new Cliente ("nome " + i, "endereco " + i, i));

        System.out.println ("-- Diferenca Simetrica clientes1 & clientes2 --");
        long t = System.currentTimeMillis();
        Set<Cliente> clientes3 = diferencaSimetrica (clientes1, clientes2);
        t = System.currentTimeMillis() - t;
        System.out.println ("Tamanho da diferenca = " + clientes3.size());
        System.out.println ("Tempo para efetuar a diferenca = " + t + "ms");
    }
}

Com sua classe Cliente, o tempo para efetuar a diferença é cerca de 50 ms em uma máquina Core 2 Duo 1.86 GHz, que não é nenhum monstro de velocidade. Ou seja, você pode considerar que é razoável.

R

Thingol,

Muito obrigado pela atenção e por suas explicações. Finalizei a implementação do meu código utilizando como base o seu exemplo. Funcionou muito bem e com um otimo desempenho!
Obrigado mesmo!

M

alguem pode me ajudar a comparar os conteudos de duas ArrayList??

while (ind < lwt.size()) {

for (int a = 1; a < lwl.size(); a++)

if (lwt.get(ind).equals(lwl.get(a))) {

saida.println((lwl.get(a)));

// saida.println((String.valueOf(lwl.get(a).toUpperCase()) + " — Ja tem!!!"));

// saida.newLine();
} else {
                    // saida.println(String.valueOf(a + " - " + lwl.get(a)));

                }
            ind++;

            saida.close();
        }

este eo o trecho critico…o lwt pega as informções num banco(so uma linha) ja o lwt pega as informações no meu pc…ai teria que gravar em um arquivo txt o que nao tem no banco comparando com o que eu tenho…mas nao consegui de jeito nenhum resolver isso, usei equals, mas nada tem alguma coisa que eu poderia usar nesta bagaça??

Criado 15 de maio de 2009
Ultima resposta 14 de ago. de 2009
Respostas 9
Participantes 5