Me ajudem a entender o código desse programinha

bom pessoal resolvi após meses de estudo de java na FJ-11 decidi fazer meu primeiro programa realmente funcional.
estou catando emails de empresas de desenvolvimento na net pra enviar meu currículo e salvo num arquivo txt onde antes de enviar verifico num outro arquivo txt de emails anteiormente enviados pra ver se tem algum repetido, processo manual e cansativo , razao pela qual quis criar esse programinha.
quero que o progr delete o email repetido do arquivo emails_novos.txt
Então um colega aqui me forneceu esse codigo abaixo que faz o que eu pedi…mas to com varias duvudas que coloquei em coment e peço a ajuda de todos ai pessoal !!
abaixo:

    import java.util.*;  
    import java.io.*;  
      
    class DiferencaArquivos {  
    //abaixo: ñ entendi o parametro "final String" ! E por que tens q indicar nomeArquivoEntrada se aqui será um conjunto e quem le e precisa da referencia do nome do orquivo de onde sera lido é o BufferedReader?  
        private Set<String> lerArquivo (final String nomeArquivoEntrada) throws IOException {  
            Set<String> emails = new TreeSet<String>(new Comparator<String>() { // aqui um conjunto...ok,  
                public int compare (String s1, String s2) { // ñ entendi essa comparação -ñ é lida uma string p/vez do arq. origem?  
                    return s1.compareToIgnoreCase (s2);  
                }  
            });  
            BufferedReader br = new BufferedReader (new FileReader (nomeArquivoEntrada)); // ok..o BufferedReader localiza o arq p/ ler  
            for (String linha = br.readLine(); linha != null; linha = br.readLine()) { //aqui ok tb.. um FOR pra ler todas linhas  
                String email = linha.trim(); // tranquilo... tirou espaços em bco a esq e a dir antes de guardar na variavel  
                if (email.length() > 0) { // ok... um testezinho pra não gravar string em bco  
                    emails.add (email.trim());   
                } //acima: ... já nao tirou os espaços 2 linhas acima desta? pensei q devia passar só "emails.add (email);"  
            }  
            br.close();  
            return emails;  
        }  
        private void gravarArquivo (final String nomeArquivoSaida, Set<String> emails) throws IOException {  
            PrintWriter pw = new PrintWriter (nomeArquivoSaida);  
            for (String email : emails) {  
                pw.println (email);  
            }  
            pw.close();  
        }  
        public static void main (String[] args) throws Exception {  
            DiferencaArquivos da = new DiferencaArquivos();  
            Set<String> emailsEnviados = da.lerArquivo (args[0]); // tem alguma validade esse parametro??  
            Set<String> emailsAEnviar = da.lerArquivo (args[1]); // idem aqui  
            Set<String> resultado = new TreeSet<String>();  
            // Queremos remover, de emailsAEnviar, todos os emails que estão em emailsEnviados  
            resultado.addAll (emailsAEnviar);  
            resultado.removeAll (emailsEnviados);  
            da.gravarArquivo (args[2], resultado); // achei que o parametro aqui devia ser apenas "resultado"  
        }  
    }  

Não seria melhor então ir criando o seu próprio ao invés de analisar esse?
São muitas duvidas, tente criar algo mais simples, vá pesquisando e aprimorando até chegar onde quer.

Uma dica, claro que pode me ignorar … :stuck_out_tongue:

Estou tentando isso paralelamente já. Mesmo assim achei esse codigo muito enriquecedor pra mim e por isso desejo entende-lo. grato pela sugestao

[quote=rafaelczy]bom pessoal resolvi após meses de estudo de java na FJ-11 decidi fazer meu primeiro programa realmente funcional.
estou catando emails de empresas de desenvolvimento na net pra enviar meu currículo e salvo num arquivo txt onde antes de enviar verifico num outro arquivo txt de emails anteiormente enviados pra ver se tem algum repetido, processo manual e cansativo , razao pela qual quis criar esse programinha.
quero que o progr delete o email repetido do arquivo emails_novos.txt
Então um colega aqui me forneceu esse codigo abaixo que faz o que eu pedi…mas to com varias duvudas que coloquei em coment e peço a ajuda de todos ai pessoal !!
abaixo:

[code]
import java.util.;
import java.io.
;

class DiferencaArquivos {  
//abaixo: ñ entendi o parametro "final String" ! E por que tens q indicar nomeArquivoEntrada se aqui será um conjunto e quem le e precisa da referencia do nome do orquivo de onde sera lido é o BufferedReader?  
    private Set<String> lerArquivo (final String nomeArquivoEntrada) throws IOException {  
        Set<String> emails = new TreeSet<String>(new Comparator<String>() { // aqui um conjunto...ok,  
            public int compare (String s1, String s2) { // ñ entendi essa comparação -ñ é lida uma string p/vez do arq. origem?  
                return s1.compareToIgnoreCase (s2);  
            }  
        });  
        BufferedReader br = new BufferedReader (new FileReader (nomeArquivoEntrada)); // ok..o BufferedReader localiza o arq p/ ler  
        for (String linha = br.readLine(); linha != null; linha = br.readLine()) { //aqui ok tb.. um FOR pra ler todas linhas  
            String email = linha.trim(); // tranquilo... tirou espaços em bco a esq e a dir antes de guardar na variavel  
            if (email.length() > 0) { // ok... um testezinho pra não gravar string em bco  
                emails.add (email.trim());   
            } //acima: ... já nao tirou os espaços 2 linhas acima desta? pensei q devia passar só "emails.add (email);"  
        }  
        br.close();  
        return emails;  
    }  
    private void gravarArquivo (final String nomeArquivoSaida, Set<String> emails) throws IOException {  
        PrintWriter pw = new PrintWriter (nomeArquivoSaida);  
        for (String email : emails) {  
            pw.println (email);  
        }  
        pw.close();  
    }  
    public static void main (String[] args) throws Exception {  
        DiferencaArquivos da = new DiferencaArquivos();  
        Set<String> emailsEnviados = da.lerArquivo (args[0]); // tem alguma validade esse parametro??  
        Set<String> emailsAEnviar = da.lerArquivo (args[1]); // idem aqui  
        Set<String> resultado = new TreeSet<String>();  
        // Queremos remover, de emailsAEnviar, todos os emails que estão em emailsEnviados  
        resultado.addAll (emailsAEnviar);  
        resultado.removeAll (emailsEnviados);  
        da.gravarArquivo (args[2], resultado); // achei que o parametro aqui devia ser apenas "resultado"  
    }  
}  

[/code][/quote]

O modificar final indica que aquela variavél (como é o caso) será imutavél. Tu não poderá dentro do seu metodo atribuir quaisquer outros valores a ela, será o que foi pasasdo ao método e ponto final!

Dê uma lida na interface Comparator, no GUJ tem vários tópicos falando dela.
Sim, o trim() já havia removido todos os espaços em branco a esquerda e/ou direita do valor daquela String. Realmente seria desncessário outro trim.
Particularmente, procuro usar isEmpty para validar se uma String é vazia, assim:

if (string.trim().isEmpty()) {...

Mas isso é questão de ponto de vista.
O args[0], args[1] são valores que são passados quanto tu iniciar o programa. Você usa o comando java classe valor valor.

Como? Veja a assinatura do método:

 private void gravarArquivo (final String nomeArquivoSaida, Set<String> emails) throws IOException {  ..

Dois parametros, portanto, está correto.

obrigado pela ajuda nel
E por que indicar nomeArquivoEntrada se aqui será um conjunto e quem le e precisa da referencia do nome do arquivo de onde sera lido é o BufferedReader ?

    private Set<String> lerArquivo (final String nomeArquivoEntrada) throws IOException {

abaixo, os dois parametros, um seria o nome do arquivo.txt (q vai receber os emails) e o outro é o cojunto final de emails filtrados? correto?

private void gravarArquivo (final String nomeArquivoSaida, Set<String> emails) throws IOException {  ..

[quote=rafaelczy]obrigado pela ajuda nel
E por que indicar nomeArquivoEntrada se aqui será um conjunto e quem le e precisa da referencia do nome do arquivo de onde sera lido é o BufferedReader ?

    private Set<String> lerArquivo (final String nomeArquivoEntrada) throws IOException {

abaixo, os dois parametros, um seria o nome do arquivo.txt (q vai receber os emails) e o outro é o cojunto final de emails filtrados? correto?

private void gravarArquivo (final String nomeArquivoSaida, Set<String> emails) throws IOException { .. [/quote]

Justamente porque a funcionalidade do métod lerArquivo é ler um arquivo :slight_smile:
O conjunto de String pode retornar qualquer coisa, nesse caso, ele extrai os e-mails contidos no arquivo.
Ele precisa do nomeDoArquivoSaida para saber onde ele deve indicar a leitura ao BufferedReader.

Sim, está correto.

ok nel
fiquei perto entender, clareia mais,
a razão de receber o parametro nomeArquivoEntrada no metodo lerArquivo é como descrevo abaixo?

 private Set<String> lerArquivo (final String nomeArquivoEntrada) throws IOException { //...recebe como parametro nomeArquivoEntrada mas ñ usa aqui...  
            Set<String> emails = new TreeSet<String>(new Comparator<String>() {  
                public int compare (String s1, String s2) {  
                    return s1.compareToIgnoreCase (s2);  
                }  
            });  
            BufferedReader br = new BufferedReader (new FileReader (nomeArquivoEntrada)); // ...mas repassa p/ ca q é de fato onde vai ser usado
            for (String linha = br.readLine(); linha != null; linha = br.readLine()) {  
                String email = linha.trim();  
                if (email.length() > 0) {  
                    emails.add (email.trim());  
                }  
            }  
            br.close();  
            return emails;  

outra coisa q nao entndi foi isso:

private Set<String> lerArquivo (final String nomeArquivoEntrada) throws IOException {  
            Set<String> emails = new TreeSet<String>(new Comparator<String>() { // cria o conj e impoe algum tipo de ordenação. pq? 
                public int compare (String s1, String s2) {  // qual o critério dessa ordenação?
                    return s1.compareToIgnoreCase (s2);  
                }  

obrigado