Armazenando dados no HashTable

5 respostas
M

Olá pessoal estou com um problema quanto ao uso do HashTable
estou fazendo um importador que pega dados de um txt , com valores separados em “;”

e quero separar esses dados de acordo com um codigo
exemplo:

nome;sobrenome;codigodobanco;

no caso, tem varios codigos , o que vou fazer é criar varios txt separando as linhas cujo codigo é o mesmo…
ex:

01.txt
02.txt
etc…

o unico problema que estou tendo é no HashTable
por exemplo:

public String percorreTexto() throws IOException{
		BufferedReader reader = new BufferedReader(new FileReader("C:\import.txt"));
		String linha = reader.readLine();
		Hashtable ht = new Hashtable();
		String dados[][] = new String[this.contaLinha()][7];
		int i = 0;		int j = 0;
			while( linha != null) {
				StringTokenizer st = new StringTokenizer(linha,";");				
				for (j = 0; j < 7; j++ ){
					dados[i][j] = st.nextToken();					
				}				
				if(this.filtraBanco().equals(dados[i][3])){
					ht.put(dados[i][3]," "+ linha);
				}	
				i++;
				linha = reader.readLine();
			}
		System.out.println(ht.toString());
		reader.close();
		return null;
	}

o filtraBanco() pega o codigo que é passado para o metodo construtor e entra em um Switch que diz o nome String de que banco ele é
01 = Banco do Brasil

dados[i][3] = é o array onde estão os dados no caso o arquivo de origem da importacao sempre possui 7 colunas sendo a 3 o nome do banco

Vamos ao problema:

tenho 4 registros por exemplo:

banco do brasil
Bradesco
caixa
banco do brasil

Ele insere no HashTable, |nome do banco|(sendo a ID) ---- |aqui vai a linha , no caso com os dados separados por “;”|

o que acontece : ele faz certo porém quando vem um registro com o mesmo ID , ou seja, do mesmo banco , ele sobreescreve os dados.
ele nao deveria somar?

abraço !

5 Respostas

T

a) A menos que você esteja criando código para rodar em Java 1.3 (eu sei, eu sei, mas isso acontece) não use StringTokenizer, mas String.split, e não use Hashtable, mas HashMap. String.split é muito mais robusto que StringTokenizer - imagine se sua linha tiver menos campos que o esperado; você vai ter problemas com o código que você nos mostrou.

b) HashMap não aceita duplicatas - se você está usando o nome do banco (argh) como chave, então apenas um valor (no caso sempre o último inserido) será posto no mapa. Comparando com um banco de dados, é como se você tivesse uma chave primária (que não aceita duplicatas).

Você pode criar uma chave combinando duas coisas que tornam a entrada única, como o nome do banco (melhor seria se fosse o código do banco, não? Ocupa menos espaço e não há problemas de minúsculas e maiúsculas) e mais alguma coisa. (É como se fosse uma chave composta).

Se você não tem como ter uma chave composta, então você pode fazer um HashMap onde a chave é o código do banco, e o valor é uma lista das linhas que têm o mesmo código do banco. Ou seja,

HashMap < String, List < String > >
davisamaral

Sei que este deve ser um exemplo apenas didático, mas para já ir começando bem procure ritirar de seu código coisas que podem variar, crescer ou diminuir de tamanho, por exemplo “um switch com nomes dos bancos”, procure colocar este tipo de coisa em arquivos properties por exemplo , assim se derrepente pretender acrecentar um outro banco não precisa mexer na implementação, é só acrescentar no arquivo. Dicas: Tente recriar o método filtraBanco(); de maneira que ele leia “N” registros no arquivo propertie e faça a comparação;(obs. properties=chave-valor ou seja um Map, ex: 01=Banco do Brasil);

outra dica: quantidades podem ser obtidas atravéz do atributo lenght (no caso de arrays) ou size (no caso de coleções), evite “chumbar” quantidades em laços de repetição…, vai por mim melhor ir começando certo!

M

beleza pessoal, valeu pelas dicas, vou tentar aqui depois posto o resultado.

abç

M

oi, então, isso foi um trabalho que recebi do meu chefe, estou començando agora no setor …
eu fiz funcionar ontem tranquilo , só que deu umas 140 linhas.

ele me falou exatamente o que voces disseram, quanto ao numero de laços de repetições…
então ele mandou eu refazer o mesmo programa em 70 linhas…(ehehehe)

consegui em 68

aqui está:

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.URL;
import java.util.StringTokenizer;

public class Dados {
	private int codBanco;
	
	public Dados(int codigo){
		this.codBanco = codigo;
	}
	public int contaLinha() throws IOException{
	    int contaL;
	    contaL = 0;
	     	File arquivo = new File("c:\import.txt");
	     	URL url = arquivo.toURL();
	    	BufferedReader in = new BufferedReader(new InputStreamReader(url.openStream()));  
	    		while (in.readLine() != null){
	    			contaL ++;
	            }
		in.close();
		return contaL;
	}
	public String filtraBanco(){
		String nomeBanco;
		nomeBanco = "";
			switch(codBanco){
				case 1:	nomeBanco = "Banco do Brasil"; break;	case 2:	nomeBanco = "Banco Real"; break;
				case 3:	nomeBanco = "Bank Boston";	break;	case 4:	nomeBanco = "Besc";	break;
				case 5:	nomeBanco = "Bradesco";	break;	case 6:	nomeBanco = "Caixa"; break;
				case 7:	nomeBanco = "Itaú";	break;	case 8:	nomeBanco = "Safra"; break;
				case 9:	nomeBanco = "Santander"; break;	case 10: nomeBanco = "Unibanco";	break;
				default: System.out.println("Nenhum Banco foi Selecionado");break;
		   }
		return nomeBanco;
	}
	public String percorreTexto() throws IOException{
		BufferedReader reader = new BufferedReader(new FileReader("C:\import.txt"));
		String linha = reader.readLine();
		String armazena; armazena = "";
		String dados[][] = new String[this.contaLinha()][7];
		int i = 0;	int j = 0;
			while( linha != null) {
				StringTokenizer st = new StringTokenizer(linha,";");				
				for (j = 0; j < 7; j++ ){
					dados[i][j] = st.nextToken();
				}
				if(this.filtraBanco().equals(dados[i][3])){
					armazena += linha + "\r\n";
					try {BufferedWriter out = new BufferedWriter(new FileWriter("C:\"+this.filtraBanco()+".txt"));
						out.write(armazena);
						out.close();
					} catch (IOException e) {
						System.out.println("Erro ao gravar arquivo");
					}
				}
				i++;
				linha = reader.readLine();
			}
		reader.close();
		return null;
	}
}

No Caso o percorreTexto() faz mais ou menos o que fazia antes em 4 metodos.
agora vou ficar o resto da tarde pra ver se consigo enxugar mais alguma coisa.

valeu ai

nieri

Pessoal, aproveitando a duvida do Marco
eu estou trabalhando com boletos , a parte da geração esta pronta,
mas agora estou fazendo a parte de leitura de codigo de barras, para
enviar o Cnab 240 para o banco e estou com dificuldades
se alguem puder ajudar eu agradeço

Criado 7 de maio de 2009
Ultima resposta 10 de jul. de 2009
Respostas 5
Participantes 4