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
[code]
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;
}[/code]
E essa é a chamada e o Comparator que utilizei
[code]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;
}
});[/code]
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.
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<Pedido>(){
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<Pedido> removeRepetidos(List<Pedido> pedidos){
Map<Integer, Pedido> t = new HashMap<>();
for (Pedido pedido : pedidos) {
Pedido p = t.get(pedido);
if (p == null || pedido.eMaisNovo(p)) {
t.put(pedido.getPedidoPk().getPddCodigo(), pedido);
}
}
return new ArrayList<>(t.values());
}
A função eMaisNovo seria o que testaria o histórico. Ela também teria que ser implementada.
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.
[quote=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.[/quote]
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.
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.[/quote]
Acho que o que ele quis dizer quando disse que não funciona é que ele não faz a função dele
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.