Count distinct names saved in txt

Asked

Viewed 312 times

3

I have a txt file with a line-separated user name below:

diego
sergio
antonio
maria
diego
antonio

Notice that names can repeat, and I would like to count and list only the distinct names.

I did this method to list the entire file:

String strPath = DIRETORIO + ARQUIVO_FILE;
if (pathExists(strPath)) {
    List<String> texto = Files.readAllLines(new File(strPath).toPath());
    for (String linha : texto) {
        System.out.println(linha);
    }
} else {
    System.out.println("arquivo não existe");
}

but I’m not sure how to adapt it into another method that makes this count of different names. How do I count this?

Note: some names may come with a point separating type surname diego.felipe, but each name and/or surname is saved per line only.

  • You want, at the end of it all, to have the total number of names without counting the repeated ones, right?

  • 1

    The first thing that came to mind was to use key-value lists, Hashmap in Java for example.

  • @jbueno exactly that

  • @Diegofelipe Ok, I made an answer with this. See if it helps you.

4 answers

6

You can use the collection HashSet, where elements are held uniquely. If you try to insert an existing element, it is not added.

The interesting thing about this collection is that the basic operations add, remove, contains and size have asymptotic complexity of O(1).

HashSet<String> nomes = new HashSet<String>();

String strPath = DIRETORIO + ARQUIVO_FILE;
if (pathExists(strPath)) 
{
    List<String> texto = Files.readAllLines(new File(strPath).toPath());
    for (String linha : texto) 
    {   
        nomes.add(linha);
    }

    System.out.println("Total de nomes: " + nomes.size());    

}
else 
{
    System.out.println("arquivo não existe");
}

3


Create a list of strings to save the names, validate if the name no longer exists inside the list before adding it, if it does not exist, add the name to the list. At the end of the iteration, use lista.size() to obtain the sum.

List<String> nomes = new ArrayList<String>();

String strPath = DIRETORIO + ARQUIVO_FILE;
if (pathExists(strPath)) 
{
    List<String> texto = Files.readAllLines(new File(strPath).toPath());
    for (String linha : texto) 
    {            
        if(!nomes.contains(linha)){
            nomes.add(linha);
        }
    }

    System.out.println("Total de nomes: " + nomes.size());    

}
else 
{
    System.out.println("arquivo não existe");
}
  • I think I got confused in the text of the question, it was to count the total number of times that distinct names appear on the list. Anyway, the mistake was mine and your answer answers to the answer.

  • @Diegofelipe This implementation counts different names. What is wrong is just the print text. Note that it checks if it has the name in the list before inserting. The only observation is that it is not efficient because the contains goes through the list with each call. The right and efficient solution is similar to this but using HashSet.

  • @utluiz actually I was emboldened to ask the question, I wanted to count the repetitions and list the count of the distinct elements, as the jbueno had already answered within the question as it was asked, and the second answer gave me an idea of how to solve the real problem, I ended up marking it as settled. It was how you vented at the finish line, having doubt and not knowing how to ask :/

  • 1

    @Diegofelipe I understand. But don’t be shy, just ask another question. : D

  • @utluiz by coincidence(or luck), one of the answers from here ended up helping me to solve the problem, I used hashmap to store and count names and repetitions.

2

Look I don’t know how it works in Java. But in C# has a set called Hashset that does not keep repeated elements. In a way you will need to do something like this for Java.

HashSet<string> devedores = new HashSet<string>();
// Podemos adicionar elementos no conjunto utilizando o método Add
devedores.Add("victor");
devedores.Add("osni");

// Para sabermos o número de elementos adicionados, utilizamos a propriedade
// Count do conjunto. Nesse exemplo elementos guardará o valor 2
int elementos = devedores.Count;

// O conjunto não guarda elementos repetidos, então se tentarmos
// adicionar novamente a string "victor", o número de elementos
// continua sendo 2
devedores.Add("victor");
  • 1

    @jbueno as incredible as it may seem, I researched and java also has this class with this operation.

0

You can further simplify the solution with HashSet, passing to List read from the file directly to the constructor of the HashSet:

String strPath = DIRETORIO + ARQUIVO_FILE;
if (pathExists(strPath)) {
    Set<String> nomes = new HashSet<>(Files.readAllLines(new File(strPath).toPath()));
    System.out.println("Total de nomes: " + nomes.size());    
} else {
    System.out.println("arquivo não existe");
}

Browser other questions tagged

You are not signed in. Login or sign up in order to post.