Listagem em ordem alfabetica com palavras com acento

21 respostas
AlanLojudice

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

21 Respostas

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.

A

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?

P

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.

AlanLojudice

A ordenacao eh feita atraves dessas duas classes.

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";
	}
    }

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.

P

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.

ViniGodoy

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

List<String> nomes = new ArrayList<String>();

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);

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

sergiotaborda

rdgc:
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.

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

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.

Edufa

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.

peczenyj

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.

AlanLojudice

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

peczenyj

vc tentou usar o to_ascii como eu sugeri?

AlanLojudice

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:

Marky.Vasconcelos

Usa oque o VinyGodoy falou já tentou?

AlanLojudice

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

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); 
			}
		}
	}
ViniGodoy

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.

ViniGodoy

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?

AlanLojudice

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

valeu

Robsonvnt

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:

ViniGodoy

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

R

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.

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

Em relação ao assunto tópico, veja este tópico http://www.guj.com.br/posts/list/48001.java

flw!

midianet

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.

Pessoal os nomes não estão errados, o nome de alguém não tem forma certa de se escrever. quer ver

Álan, Alan, vejam o acento da a diferença.

então não existe essa de escrever nome certo, o nome certo e o nome que seu pai escolheu pra você e registrou.

entao o jeito e fazer uso de algoritmos ou no banco ou na aplicação para ordenar quanto a sua necessidade.

Criado 5 de setembro de 2007
Ultima resposta 10 de jan. de 2008
Respostas 21
Participantes 11