Ordenação de listas com mais de um critério

Pessoal, preciso ordenar uma lista de objetos conforme estrutura:

class Objeto { Date data; int ord; }

Porém, precisa ter dois critérios:

Primeiro ordena pela data e depois pela ordem, ou seja, ele vai ordenar pela ordem quando houver datas iguais.

Alguém me da uma idéia de fazer isso em Java ?

Obg!!! :wink:

[quote=MrDataFlex]Pessoal, preciso ordenar uma lista de objetos conforme estrutura:

class Objeto { Date data; int ord; }

Porém, precisa ter dois critérios:

Primeiro ordena pela data e depois pela ordem, ou seja, ele vai ordenar pela ordem quando houver datas iguais.

Alguém me da uma idéia de fazer isso em Java ?

[/quote]

Só existe uma resposta a “ordenar” em java: Comparable / Comparator e Collections.sort().
(A menos, é claro, que deseje criar seus próprios algoritmos de ordenação)

Crie um Comparator e use Collections.sort();

O comparador é simples e faz exactamente o que vc falou. Primeiro compara o campo de prioridade maior , a data. se forem iguais
utiliza o campo de prioridade a seguir. Isto pode ser feito em infinitos niveis de prioridade.

É isso ai … eu estava até implementado um exemplo com Comparator, para não perder a idéia segue o exemplo, mas é tudo o que o sergio disse.

Comparador Data, fiz um exemplo rapido com o getTime(), mas não é garantido comparar com ele.

public class ComparadorData implements Comparator {

	public int compare(Object obj1, Object obj2) {
		int retorno = 0;
		if(obj1 == null || obj2 == null)
			return 0;
		
		Objeto objeto1 = (Objeto) obj1;
		Objeto objeto2 = (Objeto) obj2;
		
		if(objeto1.getData().getTime() > objeto2.getData().getTime()) {
			retorno = 1;
		} else if (objeto1.getData().getTime() == objeto2.getData().getTime()) {
			retorno = 0;
		} else {
			retorno = -1;
		}
		return retorno;
	}

Comparador do campo ord

public class ComparadorOrd implements Comparator {

	public int compare(Object obj1, Object obj2) {
		int retorno = 0;
		if(obj1 == null || obj2 == null)
			return retorno;
		
		Objeto objeto1 = (Objeto) obj1;
		Objeto objeto2 = (Objeto) obj2;
		
		if(objeto1.getOrd() > objeto2.getOrd()) {
			retorno = 1;
		} else if(objeto1.getOrd() == objeto2.getOrd()) {
			retorno = 0;
		} else {
			retorno = -1;
		}
		
		return retorno;
	}

}

Usage

ComparadorData comparadorData = new ComparadorData();
		ComparadorOrd comparadorOrd = new ComparadorOrd();
		
		List objetos<Objeto> = new ArrayList<Objeto>();
		
		Collections.sort(objetos, comparadorData) ;
		Collections.sort(objetos, comparadorOrd) ;

vlww
[]'s

[quote=lcegatti]É isso ai … eu estava até implementado um exemplo com Comparator, para não perder a idéia segue o exemplo, mas é tudo o que o sergio disse.

Comparador Data, fiz um exemplo rapido com o getTime(), mas não é garantido comparar com ele.
[/quote]

Date é um objeto comparável (implementa comparable )
Então o seu primeiro comparador pode ser apenas:
(nota: se os objetos são null deve acontecer uma exceção. Não teste se são null a menos que isso faça parte
das regras.

public class ComparadorData implements Comparator {

	public int compare(Object obj1, Object obj2) {

		Objeto objeto1 = (Objeto) obj1;
		Objeto objeto2 = (Objeto) obj2;
		
		return objeto1.getData().compareTo(objeto2.getData());

	}

O segundo seria:

public class ComparadorOrd implements Comparator {

	public int compare(Object obj1, Object obj2) {

		Objeto objeto1 = (Objeto) obj1;
		Objeto objeto2 = (Objeto) obj2;
		
                return objeto1.getOrd() - objeto2.getOrd();
	}

}

Agora isto:

Não faz o que foi pedido. Isto ordena primeiro por data. Depois ignora essa ordenação e ordena de novo por ordem.
A ideia é que ele ordene por ordem apenas quando as datas são iguais.
[/quote]

[quote=sergiotaborda][quote=lcegatti]É isso ai … eu estava até implementado um exemplo com Comparator, para não perder a idéia segue o exemplo, mas é tudo o que o sergio disse.

Comparador Data, fiz um exemplo rapido com o getTime(), mas não é garantido comparar com ele.
[/quote]

Date é um objeto comparável (implementa comparable )
Então o seu primeiro comparador pode ser apenas:
(nota: se os objetos são null deve acontecer uma exceção. Não teste se são null a menos que isso faça parte
das regras.

public class ComparadorData implements Comparator {

	public int compare(Object obj1, Object obj2) {

		Objeto objeto1 = (Objeto) obj1;
		Objeto objeto2 = (Objeto) obj2;
		
		return objeto1.getData().compareTo(objeto2.getData());

	}

O segundo seria:

public class ComparadorOrd implements Comparator {

	public int compare(Object obj1, Object obj2) {

		Objeto objeto1 = (Objeto) obj1;
		Objeto objeto2 = (Objeto) obj2;
		
                return objeto1.getOrd() - objeto2.getOrd();
	}

}

Agora isto:

Não faz o que foi pedido. Isto ordena primeiro por data. Depois ignora essa ordenação e ordena de novo por ordem.
A ideia é que ele ordene por ordem apenas quando as datas são iguais.
[/quote][/quote]

Legal meu … vlww mesmo pelas dicas :thumbup:

[quote=lcegatti]É isso ai … eu estava até implementado um exemplo com Comparator, para não perder a idéia segue o exemplo, mas é tudo o que o sergio disse.

Comparador Data, fiz um exemplo rapido com o getTime(), mas não é garantido comparar com ele.

public class ComparadorData implements Comparator {

	public int compare(Object obj1, Object obj2) {
		int retorno = 0;
		if(obj1 == null || obj2 == null)
			return 0;
		
		Objeto objeto1 = (Objeto) obj1;
		Objeto objeto2 = (Objeto) obj2;
		
		if(objeto1.getData().getTime() > objeto2.getData().getTime()) {
			retorno = 1;
		} else if (objeto1.getData().getTime() == objeto2.getData().getTime()) {
			retorno = 0;
		} else {
			retorno = -1;
		}
		return retorno;
	}

Comparador do campo ord

public class ComparadorOrd implements Comparator {

	public int compare(Object obj1, Object obj2) {
		int retorno = 0;
		if(obj1 == null || obj2 == null)
			return retorno;
		
		Objeto objeto1 = (Objeto) obj1;
		Objeto objeto2 = (Objeto) obj2;
		
		if(objeto1.getOrd() > objeto2.getOrd()) {
			retorno = 1;
		} else if(objeto1.getOrd() == objeto2.getOrd()) {
			retorno = 0;
		} else {
			retorno = -1;
		}
		
		return retorno;
	}

}

Usage

ComparadorData comparadorData = new ComparadorData();
		ComparadorOrd comparadorOrd = new ComparadorOrd();
		
		List objetos<Objeto> = new ArrayList<Objeto>();
		
		Collections.sort(objetos, comparadorData) ;
		Collections.sort(objetos, comparadorOrd) ;

vlww
[]'s[/quote]

valeu cegatti e taborda, fiz umas alterações e funcionou, a idéia então para ordenar com mais de um critério é:

Uma vez implementando o Comparator, ele lhe oferece o método abstrato “compare”, este método recebe dois objetos por parâmetro, (ambos que serão comparados) que retornam um inteiro, onde: 1 significa MAIOR, -1 MENOR e 0 IGUAIS.

Uma comparação de dois critérios pode envolver apenas uma classe, sendo:

[code]public class DoisCriterios implements Comparator {
public int compare(Object obj1, Object obj2) {
int retorno = 0;
if(obj1 == null || obj2 == null)
return 0;

	SortMe objeto1 = (SortMe) obj1;
	SortMe objeto2 = (SortMe) obj2;
	
	//maior
	if (objeto1.getDate().after(objeto2.getDate())) {
		retorno = 1;
	} 
	//menor
	else if (objeto1.getDate().before(objeto2.getDate())) {
		retorno = -1;
	} 
	//iguais ?
	else {
		if (objeto1.getOrd() > objeto2.getOrd()) {
			retorno = 1;
		} else if (objeto1.getOrd() < objeto2.getOrd()) {
			retorno = -1;
		} 
	}
	
	
	return retorno;

}
}[/code]

Como pode ser visto, o X da questão está em: Verificar o primeiro critério e depois o segundo (se houverem mais, vai verificando)

Abraços

não é necessário que sejam esses valores. O que é necessário é que :
Se igual retorna qualquer numero igual a zero (ou seja, zero)
Se menor retorna qualquer numero menor que zero.
Se maior retorna qualquer numero maior que zero.

Com isso em mente, o codigo pode ser simplificado para:

[code]public class DoisCriterios implements Comparator {
public int compare(Object obj1, Object obj2) {

	SortMe objeto1 = (SortMe) obj1;
	SortMe objeto2 = (SortMe) obj2;
	
            int differenca= objeto1.getDate().compareTo(objeto2.getDate());

	// data iguais
	if (differenca==0){
                    differenca = objeto1.getOrd() - objeto2.getOrd(); 
                     // na sua implementação faltava o igual
	}

	return differenca;

}
}[/code]

Exatamente