Listas de Strings

Pessoal estou com o seguinte problema:

tenho uma lista que tá armazenando várias strings, pode acontecer em determinados momentos que varias strings serem idênticas, quando isso ocorrer eu preciso eliminar as repetições, até aqui tudo ok, eu consegui isso usando o seguinte código:

             HashSet set = new HashSet( lista ); // lista é do tipo List
             Iterator itr = set.iterator(); 
             List lista2 = new ArrayList();
             while(itr.hasNext()){                  
                 String s="";
                 s += itr.next();  
                 lista2.add(s);
                 //System.out.println(s);
             }

porém existe ainda construções de strings que precisam ser tratadas
exemplo:

String a1 = "LOJAS RENE Brasil 2000 Bahia BA";
String a2 = "LOJAS RENE Equador 2000 Bahia BA";

pessoal imagine que essas duas strings acima estejam armazenadas na lista, depois do código acima ser executado elas ñ serão elimininadas, pois temos ainda o nome do pais que é diferente portanto são duas strings com valores diferentes, porém quando isso ocorre eu preciso fazer uma mescla dessas strings para que o resultado final seja:

String resultadofinal = "LOJAS RENE Brasil Equador 2000 Bahia BA"; ou pode ser também

String resultadofinal = "LOJAS RENE Brasil 2000 Bahia BA"; Equador

pessoal dê uma ajuda ae tô meio enrrolado com isso aqui dentro de um projeto, desde já agradesço a todos pela colaboração. Obrigado a todos.

Att,

Ângelo Santos.

cara dar uma lida nesse topico… e modifica o seu:

http://www.guj.com.br/posts/list/50115.java

flw!!

[quote=camilolopes]cara dar uma lida nesse topico… e modifica o seu:

http://www.guj.com.br/posts/list/50115.java

flw!![/quote]

[b]peço minhas sinceras desculpas a todos, sou novato no forum, já modifiquei, e agradesço pela dica. Obrigado,

Att,
Ângelo Santos.[/b]

O problema é identificar se as strings são parecidas:

  • se puder quebrar em campos e compará-los um a um é tranqüilo;
  • caso contrário, pesquise por Needleman-Wunsch ou por esta biblioteca.

[quote=TheMask][quote=angelobuild]

porém existe ainda construções de strings que precisam ser tratadas
exemplo:

String a1 = "LOJAS RENE Brasil 2000 Bahia BA";
String a2 = "LOJAS RENE Equador 2000 Bahia BA";


[/quote]

O problema é identificar se as strings são parecidas:

  • se puder quebrar em campos e compará-los um a um é tranqüilo;
  • caso contrário, pesquise por Needleman-Wunsch ou por esta biblioteca.[/quote]

Amigão, seguinte essas strings vem de um ResultSet, ou seja, são campos eu não precisaria nem quebrar, já vem pronto, eu é quem faço a concatenação e adiciono numa lista, talvez podemos criar objetos e trabalhar com isso ao invés de strings, vc tem algum exemplo de como posso fazer isso, e de maneira eficiente pode ser strings ou objetos, objetos do tipo bean por exemplo, pense na possibilidade de cerca de 3.000 mil registros daí para cima ok, logo uma comparação campo a campo precisaremos de um algoritmo eficiente, o banco que usamos é oracle na versão 8i, dava p/ fazer isso lá, mas o tempo de retorno da query tá impossibilitando essa manobra, daí a idéia de trazer esse processamento p/ a aplicação. Se tivessemos o oracle 9i já tem uma função prontinha lá que faz isso e de maneira eficiente, mas fazer o q!. Amigão desde mais uma vez meu muito obrigado a você e a todos que estão colaborando não só comigo, mas para que este forum seja o sucesso que é. Obrigado a todos

Realmente, o ideal seria você carregar os campos num objeto. Depois, sobrescreva o método hashCode e o equals para que os objetos sejam iguais na situação que você quer.

Depois, adicione todos os objetos num HashSet, que automaticamente eliminará as duplicatas de maneira BEM mais eficiente do que você fez.

Por exemplo (vou fazer com apenas 2 campos, para facilitar o exemplo. No seu caso, faça a classe carregar todo o resultset. A idéia é só trabalhar com a classe depois). A classe abaixo leva em consideração apenas o nome, desprezando o país:

[code]
public class Loja {
private String nome;
private String pais;

public Loja(String nome, String pais) {
     this.nome = nome;
     this.pais = pais;
}

@Override public int hashCode() {
       return nome.hashCode();
}

@Override public boolean equals(Object o2) {
   if (this == o2)
      return true;

   if (!(o2 instanceof Loja))
      return false;

   return o1.nome.equals(o2.nome);
}

public String getNome() {return nome;}
public String getPais() {return pais;}

}[/code]

Depois, no seu código:

[code]Set aSet = new HashSet();

while (resultSet.next()) {
Loja l = carregaLoja(resultSet);
aSet.add(l);
}[/code]

Ao final, o set irá conter uma lista de todas as lojas, sem repetições. Essa abordagem exige um pouco de memória para carregar os objetos, mas você não deve ter problemas antes de uns 300.000 objetos não repetidos.

O que eu ainda acho estranho é como o Oracle pode demorar. Normalmente, os bancos de dados são extremamente rápidos nesse tipo de pesquisa, se estiverem corretamente normalizados e indexados.

Para mais informações sobre como implementar o hash code e o equals, leia os dois primeiros itens desse capítulo do livro Effective Java.

Obrigado amigão. Seguinte no uso do objeto HasSet ele não armazenará as repetições, porém eu preciso de que os campos difrentes na repeticão dos nomes das empresas sejam concatenados com o campo correspondente. Esse exemplo faz isso?

Hummm… esse detalhe havia mesmo me escapado.

Os campos diferentes podem variar apenas no país ou em outras coisas também?

[quote=ViniGodoy]Hummm… esse detalhe havia mesmo me escapado.

Os campos diferentes podem variar apenas no país ou em outras coisas também?[/quote]

no total, minha query me dará 11 campos, desses 11, 4 campos pode variar quando houver repetição, daí preciso pegar as informações dos campos que estão variando e concatenar com o seu campo correspondente e assim ter um unico registro, porém se me permite dizer dessa forma, sem perda da informação. capos que variam pais, valor, municipio e uf. olha se ficar mais fácil p/ agente se comunicar eu tenho msn e gtallk
msn angelo100malicia@hotmail.com
gtallk angelobuild@gmail.com

Nesse caso, talvez o ideal seja você criar a classe loja suportando sets com esses valores.

Depois, faça um HashMap do nome da loja, para o objeto da loja em si.

Daí o algoritmo fica basicamente:

[code]while (resultSet.next()) {
String nome = rs.getString(“nome”);
Loja loja = mapDeLojas.get(nome);
if (loja == null) {
map.put(criaLoja(resultSet);
continue;
}

loja.getPaisSet().put(rs.getString(“pais”));
loja.getValorSet().put(rs.getDouble(“valor”));
loja.getMunicipioSet().put(rs.getString(“municipio”));
loja.getUfSet().put(rs.getString(“UF”));
}[/code]

A classe loja seria algo assim:

public class Loja { private String nome; private Set<String> municipioSet; private Set<Double> valorSet; private Set<String> ufSet; private Set<String> paisSet; //Getters setters e outras coisas }

Claro que no lugar do nome, seu map poderia usar o id do banco.

Infelizmente não tenho nenhum desses aqui no trabalho… :frowning:

Infelizmente não tenho nenhum desses aqui no trabalho… :([/quote]
olha só você pode acessar email, se puder, cria um email do gmail que por lá podemos conversar online, é só acessar, caso você quiser eu posso tá lhe enviando um convite, caso ainda não tenha email do gmail.

uma pergunta esse código ae que postaste é java 5?

public class Loja { private String nome; private Set<String> municipioSet; private Set<Double> valorSet; private Set<String> ufSet; private Set<String> paisSet; //Getters setters e outras coisas }

É sim. Em java 4 é muito similar, mas tem alguns casts.

A princípio, acho que não terei problemas, estou usando NetBeans5.5 e a jdk 1.5 na versão 11, só não tenho domínio no java 5, mas vou fazer aqui e vê o que dá daí qualquer coisa te mando o resultado ae. Desde já mais uma vez estou muito agradecido pela vossa atenção.