2

I'm trying to do a program that takes words from a file and put them into a Hashtable. Then I must do the frequency of the words and output like this : word , number of appearances. I know my add method it's messed up but i don't know how to do it. I'm new to java.

public class Hash {

private Hashtable<String, Integer> table = new Hashtable<String, Integer>();

public void readFile() {

    File file = new File("file.txt");

    try {

        Scanner sc = new Scanner(file);

        String words;

        while (sc.hasNext()) {
            words = sc.next();
            words = words.toLowerCase();

            if (words.length() >= 2) {
                table.put(words, 1);
                add(words);
            }
        }
        sc.close();

    } catch (FileNotFoundException e) {
        e.printStackTrace();
    }
}

public void add(String words) {

    Set<String> keys = table.keySet();
    for (String count : keys) {
        if (table.containsKey(count)) {
            table.put(count, table.get(count) + 1);
        } else {
            table.put(count, 1);
        }
    }
}

public void show() {

    for (Entry<String, Integer> entry : table.entrySet()) {
        System.out.println(entry.getKey() + "\t" + entry.getValue());
    }
}

public static void main(String args[]) {

    Hash abc = new Hash();

    abc.readFile();

    abc.show();
}
}

This is my file.txt

one one
two
three
two

Output :

two , 2
one , 5
three , 3
Cosmin
  • 93
  • 2
  • 9

3 Answers3

4
Set<String> keys = table.keySet();
for (String count : keys) {
    if (table.containsKey(count)) {
        table.put(count, table.get(count) + 1);
    } else {
        table.put(count, 1);
    }
}

Right now, you're incrementing the keys that are already in the map. Instead, I don't think you want to loop over anything, you just want to have the increment if condition for words, which I think actually only represents one word.

if (table.containsKey(words)) {
   table.put(words, table.get(words) + 1);
} else {
   table.put(words, 1);
}
Louis Wasserman
  • 191,574
  • 25
  • 345
  • 413
2

You can drop the add function. You attempt to increment after you have set the value to 1 Instead I would write

try (Scanner sc = new Scanner(file)) {
    while (sc.hasNext()) {
        String word = sc.next().toLowerCase();

        if (words.length() >= 2) {
            Integer count = table.get(word);
            table.put(word, count == null ? 1 : (count+1));
        }
    }
}

Note: in Java 8 you can do all this in one line, processing each line in parallel.

Map<String, Long> wordCount = Files.lines(path).parallel() 
                    .flatMap(line -> Arrays.asList(line.split("\\b")).stream()) 
                    .collect(groupingByConcurrent(w -> w, counting()));
Peter Lawrey
  • 525,659
  • 79
  • 751
  • 1,130
1

Note that

map.merge(word, 1, (c, inc) -> c + inc);

Or

map.compute(word, c -> c != null ? c + 1 : 1);

Versions are shorter and likely to be more efficient than

if (table.containsKey(words)) {
   table.put(words, table.get(words) + 1);
} else {
   table.put(words, 1);
}

And

Integer count = table.get(word);
table.put(word, count == null ? 1 : (count+1));

Suggested by people in this thread.

leventov
  • 14,760
  • 11
  • 69
  • 98