Comparando Listas aninhadas

4 respostas
Mavericks

Possuo uma lista de Pedidos, que pode possuir pedidos duplicados, por conta de um join com Histórico de pedidos.

List<Pedido> pedidos = new ArrayList<Pedido> ();

Utilizei o seguinte código para remover os pedidos duplicados

public List<Pedido> removeRepetidos(List<Pedido> pedidos, Comparator<Pedido> comparator){

	     Set<Pedido> t = new TreeSet<Pedido>(comparator);
	     t.addAll(pedidos);
	     
	     List<Pedido> pedidosClone = new LinkedList<Pedido> (t); 
             return pedidosClone;
	}

E essa é a chamada e o Comparator que utilizei

pedidos = removeRepetidos(pedidos, new Comparator<Pedido>(){

			public int compare(Pedido o1, Pedido o2) {
				
				if (o1.getPedidoPk().getPddCodigo() == o2.getPedidoPk().getPddCodigo())
					return 0;
				else
					return -1;
			}
		});

Isso funciona, consigo ficar com a lista sem elementos duplicados, mas não resolve meu problema.

Na verdade eu preciso verificar se possuo pedidos duplicados, mas remover o que tiver histórico mais antigo, mantendo o pedido com histórico mais recente.

Cada pedido possui uma lista de Históricos.

Acredito que eu preciso de outro comparator para verificar o histórico, mas não estou com uma ideia muito clara de como fazer isso.

Alguém ajuda?

4 Respostas

ViniGodoy

Como esse comparador funciona se ele está errado? Ele retorna sempre -1 caso os elementos sejam diferentes, o que significa que, sele ele comparar a com b, dirá que a < b. E se ele comparar b com a, dirá que b < a. Se funciona, foi mais um acaso azarado do destino.

O comparador correto seria:

pedidos = removeRepetidos(pedidos, new Comparator&lt;Pedido&gt;(){ public int compare(Pedido o1, Pedido o2) { return o1.getPedidoPk().getPddCodigo() - o2.getPedidoPk().getPddCodigo()); } });

Não basta alterar o comparador para incluir o histórico, pois assim ele passará a não eliminar mais, já que históricos diferentes representará registros diferentes. O que eu faria, é ao invés de usar addAll, usar um loop:

public List&lt;Pedido&gt; removeRepetidos(List&lt;Pedido&gt; pedidos){ Map&lt;Integer, Pedido&gt; t = new HashMap&lt;&gt;(); for (Pedido pedido : pedidos) { Pedido p = t.get(pedido); if (p == null || pedido.eMaisNovo(p)) { t.put(pedido.getPedidoPk().getPddCodigo(), pedido); } } return new ArrayList&lt;&gt;(t.values()); }

A função eMaisNovo seria o que testaria o histórico. Ela também teria que ser implementada.

Mavericks

Vini,

O comparator funciona, pq apenas os casos em que os objetos são iguais diferentes eles são inseridos no set, ou seja, se o resultado não for zero.
Mas de qualquer forma, como vc fez fica melhor e implementei assim.

Com relação ao histórico, não preciso tratar, quando o resultado é cartesiano ele vem como todos os históricos, que é tratado mais adiante.

Obrigado.

ViniGodoy

Mavericks:
O comparator funciona, pq apenas os casos em que os objetos são iguais diferentes eles são inseridos no set, ou seja, se o resultado não for zero.
Mas de qualquer forma, como vc fez fica melhor e implementei assim.

O comparador não serve só para testar se um elemento entra ou não no set. O set é implementado na forma de uma árvore binária. Portanto, o comparador tem que, necessariamente, dar a noção de ordem dos elementos. Do jeito que você fez, essa noção não existe, portanto, o comportamento ficará inconsistente.

Por tratar ali eu só quis dizer incluir a função que vai efetivamente descobrir qual dos dois é o mais novo. Não tenho como adivinhar como está o seu histórico, pois não conheço seus dados. :slight_smile:

Rodrigo_Sasaki

Mavericks:
Vini,

O comparator funciona, pq apenas os casos em que os objetos são iguais diferentes eles são inseridos no set, ou seja, se o resultado não for zero.
Mas de qualquer forma, como vc fez fica melhor e implementei assim.

Com relação ao histórico, não preciso tratar, quando o resultado é cartesiano ele vem como todos os históricos, que é tratado mais adiante.

Obrigado.

Acho que o que ele quis dizer quando disse que não funciona é que ele não faz a função dele :slight_smile:

Dizer se é igual ou diferente é função do equals, não do compareTo.

o compareTo deve dizer quem vem primeiro e quem vem depois, se for só pra eliminar os duplicados basta sobrescrever equals e hashCode e jogar todos eles em um HashSet.

Criado 23 de janeiro de 2013
Ultima resposta 23 de jan. de 2013
Respostas 4
Participantes 3