Count same lines in a file, JAVA

♀尐吖头ヾ 提交于 2019-12-11 07:36:11

问题


I have a text file which has lines of animals, who occur on this list from 1 to n times. I need to read this text file, count all the separate animal occurences, sort them from highest to lowest and put them in a jtable.

For example, the text file looks like this:

dog
sheep
cat
horse
cat
tiger
cat
cat
tiger

I need to count all the same occurences like so:

dog 1
sheep 1
cat 4
horse 1
tiger 2

And then sort them from highest to lowest and somehow put them into a table, so that would be:

Animal name: count
cat          4
tiger        2
dog          1
sheep        1
horse        1

So, for now my specific question is how can i count the matches for all the separate animals?

Thanks for the help!


EDIT

The answer provided by Vishal Kamat, has worked, my animals and their occurences have been counted with this code:

java hashmap word count from a text file

Now, I just need to put all this information to a new jtable


回答1:


Just use the switch-case. You can use a counter for each animal. Or use an arrayList where you can store the amount of each animal...

   String line = reader.readLine();
        while (line != null) {
            switch (line) {
                case "cat":
                catCounter++;
                break;
                case "dog":
                dogCounter++;
                break;
                case "horse":
                horseCounter++;
                break;
                case "tiger":
                tigerCounter++;
                break;
                case "sheep":
                sheepCounter++;
                break;
                default:
                break;
            }
        }



回答2:


Unfortunately I'm not able to write and test a code, but I am able to give you a path to do the thing you want.

You can use Regex for matching how many times, let's say "cat" was mentioned in the text file.

Perhaps this would help: http://code.runnable.com/UqUJWzqM7L8-AAFT/how-to-count-the-number-of-matching-string-in-java-for-regex

I did not write the code, credits to Mirang.




回答3:


You can have a Map<String, Integer> where key would be the animal name and count would be the occurances so far. Everytime you read an animal, get the value from the map and increment it. Finally you can sort the Map using the integer value of the count and store in the table.




回答4:


You can try this.if it is convenient to you.

HashMap map=new HashMap();
HashSet set=new HashSet();
FileInputStream fis=new FileInputStream(file);
StreamTokenizer st=new StreamTokenizer(fis);
while(st.nextToken()!=StreamTokenizer.TT_EOF){

     Integer count=1;
     String s;
     switch(st.ttype)
     {
          case StreamTokenizer.TT_WORD:
          s=st.sval;
          if(map.containsKey(s))
          {
               count=(Integer)map.get(s);
               count++;
               map.put(s,count);
               set.add(s);
          }
          else
          {
               map.put(s,count);
               set.add(s);
          }
          break;
     }
}
//now you have a collection of words with their frequency.it will automatically sort numeric values
System.out.println("frequency of each word in file");
Iterator iter=set.iterator();//get all the keys from the HashSet

//display them with help of Iterator interface
while(iter.hasNext())
{
     String s=(String)iter.next();
     Integer count=(Integer)map.get(s);
     System.out.println("frequency of "+s+" : "+count);
}



回答5:


Most of the answers here are either too complicated or don't implement frequency distribution properly. Following is my solution:

Map<String, Integer> frequency = new HashMap<>();

try (Scanner scanner = new Scanner(new File("path/to/file"), "UTF-8")) {
    while (scanner.hasNext()) {
        String temp = scanner.nextLine();
        if(frequency.containsKey(temp)) {
            Integer count = frequency.get(temp);
            frequency.put(temp, Integer.sum(count, 1));
        } else {
            frequency.put(temp, 1);
        }
    }
}

The key of the Map contains the animal name and value (which is an Integer) contains the occurrences of the animal names read so far. After each iteration, check if the animal name is in the key. If yes, increment its value. Otherwise, put a new key-value pair with the value as 1. Once the Map has been populated, you can use it as you please.




回答6:


You can do this with Java 8 Streams. This solution is compact and quite expressive. It creates a Stream of lines read from the file. Each unique line becomes a group, it counts the entries in each group, and then sorts the groups by their value, in descending order.

Now since you want to put these in a JTable, you need a two dimentional array.

package com.test;

import java.io.IOException;
import java.net.URISyntaxException;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.Arrays;
import java.util.Comparator;
import java.util.Map;
import java.util.function.Function;
import java.util.stream.Collectors;
import java.util.stream.Stream;

import javax.swing.JTable;

public class TestCount {

    public static void main(String args[]) throws URISyntaxException, IOException {
        // for absolute path use: Paths.get("/path/to/animals.txt")
        try (Stream<String> stream = Files.lines(Paths.get(TestCount.class.getClassLoader().getResource("animals").toURI()))) {

            Object[][] data = stream
                    .collect(Collectors.groupingBy(Function.identity(), Collectors.counting())).entrySet().stream()
                    .sorted(Map.Entry.comparingByValue(Comparator.reverseOrder()))
                    .map((entry) -> new Object[] { entry.getKey(), entry.getValue() })
                    .toArray(Object[][]::new);

            // print the data
            for (Object[] row : data) {
                System.out.println(Arrays.toString(row));
            }

            // create the JTable
            new JTable(data, new String[] { "animal", "count" });
        }
    }
}

If you already have a sorted Map you can covert to a two dimensional array like so:

Object[][] data = m1.entrySet().stream()
        .map((entry) -> new Object[] { entry.getKey(), entry.getValue() })
        .toArray(Object[][]::new);


来源:https://stackoverflow.com/questions/36967655/count-same-lines-in-a-file-java

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!