Listagem em ordem alfabetica com palavras com acento

Quero puxar uma lista de nomes no banco de dados por ordem alfabética.

O problema é que quando mando listar, os nomes sem e com acento ficam separados, por exemplo:

QUOTE
Marcio Teixeira
Marcos Leite
Márcio Souza

Veja que os dois Márcios (com e sem acento) ficam separados por causa do ACENTO.

Como posso fazer uma lista correta???

Desde já agradeço.

Alan Lojudice

Entenda que a ordenação está correcta os nomes é que estão errados.
Não tente criar uma gambiarra que irá defender quem colocou os dados errados.

Qual o SGBD?

A ordenação está sendo feita na consulta ao banco de dados ou você escreveu código para fazer a ordenação?

Se vc faz a ordenação com o order by do sgbd, não tem como dar o efeito que você quer. Caso vocÊ recolha a lista do sgbd e ordene em Java, então você pode fazer o que quiser e não é muito difícil, porém vai ser um pouco trabalhoso.

A ordenacao eh feita atraves dessas duas classes.

[code] public ActionForward listarOcorrenciasArea(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception, PrincipiaException {

// ----------------
ListarTodasOcorrenciasForm formReal = (ListarTodasOcorrenciasForm) form;

// busca todas as ocorrencias existentes no banco
List listaComTodasAsOcorrencias = AtendimentoFacadeImpl.getInstance().getListaOcorrencias();

// nesta lista ficarão todas as ocorrencias que possuem a area de atuação selecionada
List listaComOcorrenciasEncontradas = new ArrayList();

// 'for' que passará por todas as ocorrencias
for (int i = 0; i < listaComTodasAsOcorrencias.size(); i++) {

    // ----------------
    Ocorrencia ocorrencia = (Ocorrencia) listaComTodasAsOcorrencias.get(i);

    // verifica se o 'oid' da area de atuação da ocorrencia é igual ao selecionado pelo usuario 
    String oidAreaDeAtuacaoDaOcorrencia = getOidDaAreaDeAtuacaoSelecionada(ocorrencia);	    
    if (oidAreaDeAtuacaoDaOcorrencia.equals(formReal.getOidAreaDeAtuacao())) {		
	// adciona a ocorrencia na lista 
	listaComOcorrenciasEncontradas.add(ocorrencia);
    }
}
request.setAttribute("listaDeAreasDeAtuacao", carregarListaDeAreasDeAtuacao());
request.setAttribute("listaDeOcorrenciasEncontradas", listaComOcorrenciasEncontradas);
System.out.println("Listagem por area de atuacao realizada com sucesso....");
return mapping.findForward("mesmaPagina");

}

/**
 * Este metodo vai retornar o oid da area de atuacao desta ocorrencia...
 * @param ocorrencia
 * @return
 */

private String getOidDaAreaDeAtuacaoSelecionada(Ocorrencia ocorrencia) {


try {

    EmAtendimentoTelefonico atendimento = (EmAtendimentoTelefonico) ocorrencia.getListaEstados().get(0);
    List listaCaracterizacaoAreaDeAtuacaoRaiz = atendimento.getListaCaracterizacaoAreaDeAtuacaoRaiz();
    CaracterizacaoAreaDeAtuacaoRaiz caracterizacaoAreaDeAtuacaoRaiz = (CaracterizacaoAreaDeAtuacaoRaiz) listaCaracterizacaoAreaDeAtuacaoRaiz.get(0);
    ValorAreaDeAtuacao areaDeAtuacao = (ValorAreaDeAtuacao) caracterizacaoAreaDeAtuacaoRaiz.getListaValoresAreaDeAtuacao().get(0);

    return areaDeAtuacao.getAreaDeAtuacao().getOid() + "";
} catch (Exception e) {
    return "Oid Invalido";
}
}
[/code]

Ai depois esses valores sao buscados no banco postgre. E sao carregados em um combo… Ai se nesse combo tiver palavras assim Alan, Áriel, MArcors e Pedro.

No combo carrega nessa ordem
Alan
Marcos
Pedro
Áriel.

A questão não é certo e errado… Se um chama Marcio e outro Mércio, então o nome deles não é igual e não necessariamente precisa estar junto na ordenação.

o fato é que a != á, e se o nome é igual, então tem um erro ai, ou os dois deverima ter acento ou nenhum deles, ai sim na ordenação eles ficariam juntos.

Para ordenar uma lista de Strings com acento, use um Collator:

[code]List nomes = new ArrayList();

nomes.add(“Vinicius”);
nomes.add(“Vinícius”);
nomes.add(“Âron”);
nomes.add(“Bola”);
nomes.add(“Carvalho”);
nomes.add(“Márcio”);
nomes.add(“Marcelo”);

Collections.sort(nomes, Collator.getInstance());

for (String nome : nomes)
System.out.println(nome);[/code]

Agora… com o seu código fica difícil saber como ordenar. Talvez o código acima te dê algumas idéias.

[quote=rdgc][quote=sergiotaborda]Entenda que a ordenação está correcta os nomes é que estão errados.
Não tente criar uma gambiarra que irá defender quem colocou os dados errados.[/quote]

Não entendi pq os nomes estariam errados… Pq ‘Márcio’ está errado e ‘Marcio’ está correto?!
[/quote]

Convenhamos que só existe uma forma correcta de escrever o nome. Portanto a outra está errada.
Sérgio escreve-se com acento , e embora eu escreve muitas vezes sem, isso não significa que está certo.

Depende

Já vi Sérgio e Sergio, Suélen e Suelen, você encontra cada coisa em listagens de escola, e são os nomes que estão registrados em cartório. São nomes diferentes, apesar de serem pronunciados igualmente.

Se for no Postgresql, vc pode usar a função to_ascii

to_ascii(text [, codificação]) – Converte texto em outras codificações em ASCII

ex:
to_ascii(‘Conseqüência’) -> Consequencia

Ou seja, vc pode fazer um order by to_ascii(campo)

A função to_ascii permite apenas a conversão das codificações LATIN1, LATIN2, LATIN9 e WIN1250.

A questão não é se tem acento o se não tem acento. O q esta errado é uma lista q tenha os nomes Alan, Álan, Pedro. Virem listados assim Alan, Pedro e Álan.

Eu eu uso o postgre e uso o ascii como encolding.

Vcs sabem se tenho q mudar algo no banco, o que tenho que fazer pra listar isso corratamente??

Obrigado

Alan

vc tentou usar o to_ascii como eu sugeri?

Sim, mas nao deu certo.
Se eu dou um select da esse erro
ERROR: encoding conversion from SQL_ASCII to ASCII not supported.

Sei la o que fazer pra deixar na ordem isso viu :roll:

Usa oque o VinyGodoy falou já tentou?

Eu acabei usando umas classes aqui que me passaram…E deu certo…Vou repassar pra vcs caso alguem tenha interesse ou o mesmo problema.

[code] private static Map<String, String> letrasComAcento_SemAcento = new HashMap<String, String>();
static {
letrasComAcento_SemAcento.put(“À”, “A”);
letrasComAcento_SemAcento.put(“à”, “a”);
letrasComAcento_SemAcento.put(“Á”, “A”);
letrasComAcento_SemAcento.put(“á”, “a”);
letrasComAcento_SemAcento.put(“”, “A”);
letrasComAcento_SemAcento.put(“â”, “a”);
letrasComAcento_SemAcento.put(“Ô, “A”);
letrasComAcento_SemAcento.put(“ã”, “a”);

	letrasComAcento_SemAcento.put("È", "E");
	letrasComAcento_SemAcento.put("è", "e");
	letrasComAcento_SemAcento.put("É", "E");
	letrasComAcento_SemAcento.put("é", "e");
	letrasComAcento_SemAcento.put("Ê", "E");
	letrasComAcento_SemAcento.put("ê", "e");
	
	letrasComAcento_SemAcento.put("Ì", "I");
	letrasComAcento_SemAcento.put("ì", "i");
	letrasComAcento_SemAcento.put("Í", "I");
	letrasComAcento_SemAcento.put("í", "i");
	letrasComAcento_SemAcento.put("Î", "I");
	letrasComAcento_SemAcento.put("î", "i");
	
	letrasComAcento_SemAcento.put("Ò", "O");
	letrasComAcento_SemAcento.put("ò", "o");
	letrasComAcento_SemAcento.put("Ó", "O");
	letrasComAcento_SemAcento.put("ó", "o");
	letrasComAcento_SemAcento.put("Ô", "O");
	letrasComAcento_SemAcento.put("ô", "o");
	letrasComAcento_SemAcento.put("Õ", "O");
	letrasComAcento_SemAcento.put("õ", "o");
	
	letrasComAcento_SemAcento.put("Ù", "U");
	letrasComAcento_SemAcento.put("ù", "u");
	letrasComAcento_SemAcento.put("Ú", "U");
	letrasComAcento_SemAcento.put("ú", "u");
	letrasComAcento_SemAcento.put("Û", "U");
	letrasComAcento_SemAcento.put("û", "u");
	
	letrasComAcento_SemAcento.put("Ç", "C");
	letrasComAcento_SemAcento.put("ç", "c");
}

private static class ComparadorDeAreaDeAtuacaoPelaDescricao implements Comparator<AreaDeAtuacao> {
	
	public int compare(AreaDeAtuacao a1, AreaDeAtuacao a2) {
		
		try {
			
			StringBuilder descricao1 = new StringBuilder(a1.getDescricao());
			StringBuilder descricao2 = new StringBuilder(a2.getDescricao());
			
			if (descricao1.toString().equals(descricao2.toString())) {
				return 0;
			}
			
			// -------------
			tirarAcentoDaPrimeiraLetraSePossivel(descricao1);
			tirarAcentoDaPrimeiraLetraSePossivel(descricao2);
			
			/*
			 * caso os dois tenham a mesma primeira letra então compara normal
			 * sem utilizar as primeiras letras modificadas...
			 * para que o acento venha depois com certeza....
			 */
			if (descricao1.charAt(0) == descricao2.charAt(0)) {
				return a1.getDescricao().compareTo(a2.getDescricao());
			}
			
			// compara com as letras modificadas
			return descricao1.toString().compareTo(descricao2.toString());
		} catch (Exception e) {
			return 0;
		}
	}

	private void tirarAcentoDaPrimeiraLetraSePossivel(StringBuilder texto) {
		
		String primeiraLetra = texto.substring(0, 1);
		boolean primeiraLetraPossueAcento = letrasComAcento_SemAcento.containsKey(primeiraLetra);
		if (primeiraLetraPossueAcento) {
			String primeiraLetraSemAcento = letrasComAcento_SemAcento.get(primeiraLetra);
			texto.replace(0, 1, primeiraLetraSemAcento); 
		}
	}
}[/code]

Que complicação…

Pq não usou o Collator como eu sugeri?
Aliás, você tentou usar o Collator?

Já é uma classe pronta, faz exatamente o que você queria e ainda respeita a ordenação em diferentes países, se for o caso.

Seu comparador ficaria assim:

private static class ComparadorDeAreaDeAtuacaoPelaDescricao implementsComparator<AreaDeAtuacao> { public int compare(AreaDeAtuacao a1, AreaDeAtuacao a2) { return Collator.getInstance().compareTo(a1.getDescricao(), a2.getDescricao()); } }

Um pouco mais simples, não acha?

A valeu Vinicius. Realmente é mais facil, ja estou implementando para usar da sua maneira.

valeu

use o
ENCODING = ‘LATIN1’
na criação do banco de dados
não ordene pela sua aplicação
se o SGDB tem ferramentas para isso pra que fazer
imagine se o resultado da consulta for muito grande

:wink:

Tem coveiro desenterrando tópico por aí… :lol: