Ola pessoal, tenho um pequeno sistema de registo de estudantes em Java, com banco de dados mysql, queria que me ajudassem a solucionar o seguinte problema. Na digitacao de dados, os nomes dos estudantes foram mal digitados, isto porque, possivelmente o operador usou o tabulador e nao controlou os espacos. O que ta a acontecer é que muitas vezes quando tento pesquisar um registo usando o LIKE, nos casos em que existe esse erro, ele nao encontra o registro. Sao situacoes do tipo:
mario david matsinhe
ele encontra este nome porque nao tem o referido problema
casos como:
mario david matsinhe
mario david matsinhe
mario david matsinhe
nao sao reconhecidos. gostaria que me ajudassem, atraves duma query ou dum algoritmo a detectar e resolver estas situacoes. O banco de dados ta com cerca de 15000 registos. To a pensar em usar a classe String tokenizer (para eliminar os espacos), mas nao domino. Peco que me deem uma orientacao
// nesse exemplo usamos o ponto como separador
String semPontos;
StringTokenizer aux = new StringTokenizer(args[i], ".");
while(aux.hasMoreTokens()){
semPontos += aux.nextToken();
}
É recomendável pegar um tempinho e escrever um programa que normalize os nomes no seu banco de dados, para que você não tenha mais esse problema.
Por exemplo, deixe os nomes todos em maiúsculas, e com apenas um espaço entre cada palavra.
Dica: prefira não usar StringTokenizer; é uma classe muito antiga e difícil de usar - e a própria documentação indica para não usá-la em novos projetos. (Só que os livros didáticos ainda continuam a ensiná-la, provavelmente porque os professores nunca atualizaram seus livros )
class NormalizarNome {
/**
* Normaliza os nomes (mas não remove os acentos).
* Nós apenas passamos os nomes para maiúsculas e
* removemos os espaços e tabulações excedentes.
* Pode-se modificar esta rotina para implementar
* melhores normalizações (por exemplo, remover
* caracteres especiais e tirar os acentos das palavras.)
* @param nome O nome a ser normalizado.
* @return O nome normalizado.
*/
public static String normaliza (String nome) {
String ret;
// Passar o nome para maiúsculas
ret = nome.toUpperCase();
// Trocar os espaços duplicados, tabulações etc. por um espaço
ret = ret.replaceAll ("\\s+", " ");
// Remover o espaço no início
ret = ret.replaceAll ("^\\s+", "");
// Remover o espaço no fim
ret = ret.replaceAll ("\\s+$", "");
return ret;
}
/**
* Exemplo de uso.
*/
public static void main(String[] args) {
String[] teste = {
"\tmario david matsinhe",
" mario david \tmatsinhe",
"mario david matsinhe ",
"mario david matsinhe"
};
for (int i = 0; i < teste.length; ++i) {
System.out.println ("[" + normaliza (teste[i]) + "]");
}
}
}
Só tem um detalhe. Desde o Java 5, o StringTokenizer deve ser substituído pelo método split.
E a classe StringBuilder deve substituir a classe StringBuffer.
O código do Hugo Pinho, hoje em dia, fica assim:
[code]package string;
import java.util.StringTokenizer;
class ValidandoString {
public static void main(String[] args) {
String texto = “Texto a ser Corrigido.”;
StringBuilder textoCorrigido = new StringBuilder();
"Só tem um detalhe. Desde o Java 5, o StringTokenizer deve ser substituído pelo método split.
E a classe StringBuilder deve substituir a classe StringBuffer.
O código do Hugo Pinho, hoje em dia, fica assim:"
Texto de ViniGodoy
Porque a o StringTokenizer deve ser substituido.
“Por que o split faz a mesma coisa, de uma maneira mais rápida, mais simples e mais poderosa. Além disso, a classe foi mantida só por questões de legado .”
Na documentação da Oracle não diz que o split e mais rápido,mais simples nem mais poderoso.Depois de dar uma googlada achei um link interessante.
Um teste realizado que transforma double e ints em uma string com um milhão de doubles deu isso aqui:
Scanner: 10642 ms
Split: 715 ms
StringTokenizer: 544ms
JFastParser: 290ms
Não citei a documentão, era eu que estava falando isso.
Ele é mais poderoso por trabalhar com expressões regulares. Só isso já permite um conjunto muito mais complexo de tokens, e muito mais interessante também.
Ele é mais simples por retornar os dados em estruturas que podem ser percorridas com o for each. Basta comparar qualquer código usando split com um código usando o Tokenizer, para você ver que tem bem menos boilerplate.
Ele é mais rápido por usar o mecanismo de expressões regulares. Talvez, no caso exclusivo de tokens muito simples, como o espaço, realmente não seja. Mas essa não é a única situação onde precisamos quebrar dados em tokens. Seu benchmark trata apenas do caso relevante para a API JFastParser (quebrar uma String em doubles).
O que citei da documentação é a observação gigante da Oracle dizendo que a StringTokenizer deveria ser descontinuada. Isso também significa que provavelmente essa classe não terá otimizações da Oracle no futuro, enquanto a API de Regex certamente terá.