Problemas com removeAll de List

4 respostas
Tchello

Boa tarde pessoal!

Então, venho até aqui pra perguntar-lhes sobre esse método mágico.

removeAll é um método abstrato da interface List implementado pela ArrayList, etc.

Ele recebe como parâmetro outra collection e compara os elementos das removendo da original os que aparecem na collection passada pra esse método.
Enfim, fiz um teste com Strings e funcionou.

Depois fiz outro teste com objetos meus e nada da bagaça funcionar.
Sei que devo sobrescrever o método equals, pra que ele possa comparar os objetos e assim o fiz.
Vejam:

List<Pessoa> lista1 = new ArrayList<Pessoa>();
            
            Pessoa p = new Pessoa();
            p.setId(1);
            p.setNome("ra");
            lista1.add(p);

            Pessoa p1 = new Pessoa();
            p1.setId(2);
            p1.setNome("ra2");
            lista1.add(p1);
            
            Pessoa p2 = new Pessoa();
            p2.setId(3);
            p2.setNome("ra3");
            lista1.add(p2);
            

            List<Pessoa> lista2 = new ArrayList<Pessoa>();

            Pessoa p10 = new Pessoa();
            p10.setId(1);
            p10.setNome("ra");
            lista2.add(p10);
            
            Pessoa p11 = new Pessoa();
            p11.setId(12);
            p11.setNome("ra");
            lista2.add(p11);


            if(lista1.removeAll(lista2))
                System.out.println("RemoveAll funfou\n");  //NEM ENTRA AQUI
            
            System.out.println("Lista 1");  //DEVERIA SOBRAR APENAS OS elementos 2 e 3
            for(Pessoa string : lista1){
                System.out.println("ID [ "+string.getId()+" ] Pessoa: "+string.getNome());
            }
            System.out.println("Lista 2");
            for(Pessoa pessoa : lista2){
                System.out.println("ID [ "+pessoa.getId()+" ] Pessoa: "+pessoa.getNome());
            }

Agora a classe pessoa:

public class Pessoa implements Serializable, CycleRecoverable, Comparable { //ignorem essas interfaces, é que pessoa é uma entidade

      private int id;

...
     @Override
    public boolean equals(Object OBEJETO) {
        if (OBEJETO instanceof Pessoa) {
            Pessoa Pobj = (Pessoa) OBEJETO;
            return Pobj.getId() == this.id;
        } else {
            return false;
        }
    }

    @Override
    public int hashCode() {
        int hash = 5;
        hash = 53 * hash + this.id;
        return hash;
    }

Alguma idéia do por quê do removeAll nao funcionar com meu objeto?
Preciso disso =Z
Obrigado!!

4 Respostas

F

vc está mandando remover da lista1 a lista2…mas em nenhum momento vc adicionou a lista 2 na lista 1…logo sempre seu if retornará false…não entrando na condição do “if”

Tchello

Exatamente, eu quero remover a lista2 da lista1. Não é necessário adiciona-las, por isso sobrescrevi o método equals da classe Pessoa pra poder compara-las.

A propósito, fiz mais alguns teste e está funcionando, é que essa classe está disponibilizada por um WebService e não sei porque ele não ta passando a nova versão da classe Pessoa pro cliente, mesmo ele tendo atualizado o wsdl. Vai entender.

Podem trancar o tópico, pelo menos fica como referência.

Vlw!

rodpuc

Não encontrei erros no seu código, mas estava aqui pensando, e vc tem ctza que o removeAll usa o equals? Acredito que pode usar o “=”, ou seja, só removeria se realmente eles forem o MESMO objeto, e não objetos com o mesmo id como vc quer.

Acho q dá pra vc testar assim: se vc inserir a mesma Pessoa nas 2 listas e depois dar um removeAll, se funcionar é pq minha teoria deve estar correta.

Nessa caso vc podia fazer um “meuEquals” que faz a compraração pelo id, do jeito q vc quer. Daí vc itera e faz tdo na mão msm.

Espero ter ajudado, abraço

Lavieri

posta tua classe inteira, pra poder achar o erro... a classe pessoa, e so pra falar mesmo... removeAll é um método implementado por AbstractCollection

public boolean removeAll(Collection<?> c) {
	boolean modified = false;
	Iterator<?> e = iterator();
	while (e.hasNext()) {
	    if (c.contains(e.next())) {
		e.remove();
		modified = true;
	    }
	}
	return modified;
    }
ele é assim ... logo ele usa contains que por sua vez usa equals e não ==
public boolean contains(Object o) {
	Iterator<E> e = iterator();
	if (o==null) {
	    while (e.hasNext())
		if (e.next()==null)
		    return true;
	} else {
	    while (e.hasNext())
		if (o.equals(e.next()))
		    return true;
	}
	return false;
    }

........

aparentemente seu código ta certo, então posta tua classe Pessoa toda ai ^^ que é pra dar uma olhada melhor

........

eu testei seu código aqui... e ele funcinou perfeitamente.... imagino que o que vc possa estar errado seja

public void setId(int id) {
        id = id; //vc pode ter esquecido o this aqui
       //ou
       this.id = this.id; //ou ter esquecido aqui
    }

       //ou então o seu getId() que esta errado
     public int getId() { return id; }

aqui eu testei e o código funcionou o resultado foi assim...

RemoveAll funfou

Lista 1
ID [ 2 ] Pessoa: ra2
ID [ 3 ] Pessoa: ra3
Lista 2
ID [ 1 ] Pessoa: ra
ID [ 12 ] Pessoa: ra
Ps.: eu dei CTRL + C ... CTRL + V no seu codigo... so adciona a parte que faltava
private int id;
    private String nome;

    public Pessoa() {};

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

    public void setId(int id) {
        this.id = id;
    }

    public int getId() {
        return id;
    }

    public String getNome() {
        return nome;
    }
//....
Criado 11 de março de 2009
Ultima resposta 11 de mar. de 2009
Respostas 4
Participantes 4