GUJ Discussões   :   últimos tópicos   |   categorias   |   GUJ Respostas

Listagem em ordem alfabetica com palavras com acento


#1

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


#2

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.


#3

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?


#4

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.


#5

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.


#6

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.


#7

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.


#8

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.


#9

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.


#10

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.


#11

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


#12

vc tentou usar o to_ascii como eu sugeri?


#13

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:


#14

Usa oque o VinyGodoy falou já tentou?


#15

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

#16

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.


#17

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?


#18

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

valeu


#19

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:


#20

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