Set gravando itens iguais na Lista

7 respostas
Fmgasparino

Olá Pessoal,

Estou com problema para utilizar o set.

Falando um pouco do meu objetivo: Preciso pegar itens de um arquivo txt, e envialo para o banco. O sistema hoje funciona, mas para processar 100.000(50mb) linhas demora em torno de 40 minutos.

Estava lendo linha por linha, e processando devidos itens, que eram 6 com 8 atributos em média. No processamento de cada item verificava se o mesmo existia no banco e caso não registrava.

Levando em conta que eu deleto todo o banco antes de processar o arquivo que é unico, pensei que fosse melhor criar uma lista e filtra-la, para otimizar o tempo e tratar se existe itens antes de enviar ao banco.

Na pesquisa encontrei o Set, que não permite itens iguais na lista. Implemente o equals do objeto e pronto, coloquei para funcionar. Infelizmente não funcionou, ele ainda salva o item ja existente no banco. Será que devo sobrecarregar outro método??

Segue o fonte:

public class DemandaFactory {

	private BufferedReader reader;
	private String linha;
	private String[] parametro;

	public DemandaFactory(BufferedReader reader) throws IOException {
		this.reader = reader;
		this.linha = this.reader.readLine();
	}

	public List<Demanda> controi() throws IOException {
		List<Demanda> demandaList = new ArrayList<Demanda>();
		while (retornaLinha()) {
		 demandaList.add((cria(this.parametro)));
		}
		
		int i=0;
		for(Demanda d: demandaList) {
			i++;
		}
		System.out.println(i);
		return demandaList;
	}

	

	public boolean retornaLinha() throws IOException {
		this.linha = this.reader.readLine();
		if (this.linha == null) {
			return false;
		} else {
			this.parametro = linha.split("\t");
			return true;
		}
	}

	public Demanda cria(String[] parametros) {

		Demanda demanda=  new Demanda();
		
		demanda.setNumeroDemanda(parametros[0]);
		demanda.setDemanda(parametros[1]);
		demanda.setTotalPF(parametros[2]);
		demanda.setArea(parametros[4]);
		demanda.setSistema(parametros[5]);
		demanda.setSituacao(parametros[6]);

		SimpleDateFormat formatoData;
		Date data;
		Locale locale = Locale.ENGLISH;

		try {
			String dataString = parametros[65].substring(0, 11).replaceAll(" ",
					"");

			if (dataString.length() == 9) {
				formatoData = new SimpleDateFormat("MMMddyyyy", locale);
			} else {
				formatoData = new SimpleDateFormat("MMMdyyyy", locale);
			}

			data = new Date(formatoData.parse(dataString).getTime());
		
			demanda.setDtInclusaoDemanda(data);
		}catch (Exception e) {
			// TODO: handle exception
		}
		
		return demanda;
	}
}

Demanda:

@Entity
public class Demanda {
	static Logger log = Logger.getLogger(Demanda.class);

	@Id
	private String numeroDemanda;
	private String demanda;
	private String area;
	private String sistema;
	private String situacao;
	private String totalPF;
	private Date dtInclusaoDemanda;

	//getters e setters 


	@Override
	public boolean equals(Object obj) {
		Demanda demanda = (Demanda) obj;
		if(this.getNumeroDemanda() == demanda.getNumeroDemanda()) {
			return true;
		}else {
			return false;
		}
	}
	
	
}

Valeu galera!!

7 Respostas

ViniGodoy

Regra de ouro do Java: Sempre que você sobrescrever o equals, você também deve sobrescrever o hashCode.

Veja aqui como faze-lo:
http://www.guj.com.br/posts/list/52485.java#276120

E baixe essa classe que facilita o processo:
http://www.guj.com.br/posts/list/101275.java#546125

O HashSet, como o próprio nome da classe indica, baseia-se no hashcode.

No seu caso, como o seu equals se baseia só no getNumeroDemanda() e se esse número não se repete, a implementação pode ser:

public int hashCode() { return getNumeroDemanda(); }

Ataxexe

Outro ponto:

this.getNumeroDemanda() == demanda.getNumeroDemanda()

Compare Strings com equals pois o operador == não é baseado em conteúdo e, sim, na referência do objeto:

this.getNumeroDemanda().equals(demanda.getNumeroDemanda())
Fmgasparino

ViniGodoy:
Regra de ouro do Java: Sempre que você sobrescrever o equals, você também deve sobrescrever o hashCode.

Veja aqui como faze-lo:
http://www.guj.com.br/posts/list/52485.java#276120

E baixe essa classe que facilita o processo:
http://www.guj.com.br/posts/list/101275.java#546125

O HashSet, como o próprio nome da classe indica, baseia-se no hashcode.

No seu caso, como o seu equals se baseia só no getNumeroDemanda() e se esse número não se repete, a implementação pode ser:

public int hashCode() { return getNumeroDemanda(); }

ViniGodoy, pelo que entendi o hashCode, irá gerar um código baseado no que eu quero me basear no equals, certo?

Como voce mencionou, realmente o numeroDemanda é o unico identificador do objeto.
Então conforme o link que me passou implementei o hashCode, seria desta forma?

public int hashCode() {  
		   return this.getNumeroDemanda().hashCode();
		}

numeroDemanda = String;

O sei continua inserindo tudo… =/

ViniGodoy

Estranho, se o número da demanda é um número, pq está numa variável do tipo String?

Pode postar o código onde você usa o set?

E não esqueça de corrigir o equals como indicado pelo ataxexe.

Fmgasparino

Realmente, o == estava causando o problema.
Difícil tirar esse habito que vem de outras linguagens… rsrs

Muito obrigado aos 2.

Atenciosamente

Ataxexe

Hehe, normal. Eu já apanhei demais com essas coisas também.

Sempre às ordens.

Fmgasparino

ViniGodoy:
Estranho, se o número da demanda é um número, pq está numa variável do tipo String?

Pode postar o código onde você usa o set?

E não esqueça de corrigir o equals como indicado pelo ataxexe.

Somente respondendo quanto a variavel numero do tipo String, é devido a regra do negócio, que trata o numero da demanda assim: “SP000000000000”, obrigando a ser String…

Valeu!!

Criado 26 de julho de 2010
Ultima resposta 26 de jul. de 2010
Respostas 7
Participantes 3