1

I typed 3 names in the file, and I wanted to write a code to count how many times each name was repeated (Example: Alex was repeated in the file 3 times..and so on). The code I wrote only counted each name once, and this is wrong because the names were repeated more than once. Can you help me with the part that could be the cause of this problem?

public class MainClass {

    public static void readFile() throws IOException {
        //File file;
        FileWriter writer=null;
        String name, line;
        List <String> list = new ArrayList <>();
        int countM = 0, countAl = 0, countAh = 0; 
        
    try 
    {
    File file = new File("\\Users\\Admin\\Desktop\\namesList.txt");
    Scanner scan = new Scanner(file); 
       
       while(scan.hasNextLine())    { 
            
        line = scan.nextLine();
        list.add(line);
        }
       
       for (int i=0; i<list.size(); i++) 
       {
           name=list.get(i);
           
           if (name.equals("Ali"))
           {
               countAl= +1;
           }
          if (name.equals("Ahmed"))
               {
                   countAh= +1;
               }
              if (name.equals("Muhammad"))
              {
                  countM = +1;
              }
       }
       

       Collections.sort(list);
       
        writer = new  FileWriter("\\Users\\Admin\\Desktop\\newNameList");

            for(int i=0; i<list.size(); i++) 
            {
                
                name = list.get(i);
                writer.write(name +"\n");
            }
             
           writer.close();
           
         System.out.println("How many times is the name (Ali) in the file? " + countAl);
         System.out.println("How many times is the name (Ahmed) in the file? " + countAh);
         System.out.println("How many times is the name (Muhammad) in the file? " + countM);
    
    }
           
     catch(IOException e) {
        System.out.println(e.toString());
    }
}
    
    public static void main(String[] args) throws IOException  {
    
        readFile();
    }
}
4
  • 2
    Please read: Why is “Can someone help me?” not an actual question? Commented Apr 26, 2022 at 18:22
  • 3
    countAl= +1; => countAl += 1; or countAl++; Commented Apr 26, 2022 at 18:23
  • If you collected the lines into a Map<String, Integer>, this would be a simple lookup against the map rather than needing individual counters Commented Apr 26, 2022 at 18:31
  • As @OneCricketeer mentioned above use Map implementation to have the count value against each name. So that you can later query the Map using key and get the count value against the name. Map<String, Long> nameCounter = new HashMap<>(); For each new name enter nameCounter.put("Ali", 1) and further check if the name exist than increment the counter like nameCounter.put("Ali", nameCounter.get("Ali")+1); Commented Apr 26, 2022 at 18:39

3 Answers 3

1

You an do this much simpler:

//Open a reader, this is autoclosed so you don't need to worry about closing it
try (BufferedReader reader = new BufferedReader(new FileReader("path to file"))) {
    //Create a map to hold the counts
    Map<String, Integer> nameCountMap = new HashMap<>();
    //read all of the names, this assumes 1 name per line
    for (String name = reader.readLine(); name != null; name = reader.readLine()) {
        //merge the value into the count map
        nameCountMap.merge(name, 1, (o, n) -> o+n);
    }
    
    //Print out the map     
    System.out.println(nameCountMap);
} catch (IOException e) {
    e.printStackTrace();
}
Sign up to request clarification or add additional context in comments.

2 Comments

I'd suggest java.nio.Files.readAllLines instead of the BufferedReader
That can be dangerous if a very large were to be read. It's being taken for granted that file he's reading is likely to be very small. I tend to err on the side of caution when there's a potential to gobble up a lot of memory.
0

try:

      for (int i=0; i<list.size(); i++) 
   {
       name=list.get(i);
       
       if (name.equals("Ali"))
       {
           countAl += 1;
       }
      if (name.equals("Ahmed"))
           {
               countAh += 1;
           }
          if (name.equals("Muhammad"))
          {
              countM += 1;
          }
   }

This works with me.

+= is not same =+

1 Comment

Oh god, two weeks to find what is the problem!, Thank youuu
0

You need to process each line bearing in mind that the file may be very large in some cases. Better safe than sorry. You need to consider a solution that does not take up so much resources.

Streaming Through the File

I'm going to use a java.util.Scanner to run through the contents of the file and retrieve lines serially, one by one:

FileInputStream inputStream = null;
Scanner sc = null;
try {
    inputStream = new FileInputStream(file_path);
    sc = new Scanner(inputStream, "UTF-8");
    while (sc.hasNextLine()) {
        String line = sc.nextLine();
        // System.out.println(line);
    }
    // note that Scanner suppresses exceptions
    if (sc.ioException() != null) {
        throw sc.ioException();
    }
} finally {
    if (inputStream != null) {
        inputStream.close();
    }
    if (sc != null) {
        sc.close();
    }
}

This solution will iterate through all the lines in the file – allowing for processing of each line – without keeping references to them – and in conclusion, without keeping them in memory:

Streaming With Apache Commons IO

The same can be achieved using the Commons IO library as well, by using the custom LineIterator provided by the library:

LineIterator it = FileUtils.lineIterator(your_file, "UTF-8");
try {
    while (it.hasNext()) {
        String line = it.nextLine();
        // do something with line
    }
} finally {
    LineIterator.closeQuietly(it);
}

Since the entire file is not fully in memory – this will also result in pretty conservative memory consumption numbers.

BufferedReader

try (BufferedReader br = Files.newBufferedReader(Paths.get("file_name"), StandardCharsets.UTF_8)) {

    for (String line = null; (line = br.readLine()) != null;) {
        // Do something with the line
    }
}

ByteBuffer

try (SeekableByteChannel ch = Files.newByteChannel(Paths.get("test.txt"))) {
    ByteBuffer bb = ByteBuffer.allocateDirect(1000);
    for(;;) {
        StringBuilder line = new StringBuilder();
        int n = ch.read(bb);
        // Do something with the line
    }
}

The above examples will process lines in a large file without iteratively, without exhausting the available memory – which proves quite useful when working with these large files.

2 Comments

Did this work for you?
I used Scanner. this is a new info for me. so, you gave me something good to know.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.