0

I'm learning about HashMaps in my Java course and I got given a task to store all the words from a text file in a HashMap and print out each unique words and the amount of occurrences of it in the file.

I couldn't figure out how to do this so searched for help here and found this link: Using HashMap to count instances

I adapted and used the Posters code into my program and it worked but I don't fully understand why and I don't want to give in something I don't understand that I didn't do myself.

I've posted my full code below but could someone please explain to me how the commented on sections function.

   public class Q3HM {
   public static void main(String[] args) {
        HashMap<String, Integer> map = new HashMap<String, Integer>(50, 10);
                               *****//Not sure what the (50,10) is for

        try {
            File input = new File("input.txt");
            Scanner read = new Scanner(new FileInputStream(input));
            ArrayList<String> list = new ArrayList<>();

            while (read.hasNext()) {
                list.add(read.next());
            }

   *******//Not sure how the below for loop works
            for (String w : list){ 
                Integer i = map.get(w);
                if(i == null){
                    map.put(w, 1);
                }
                else {
                    map.put(w, i+1);
                }
            }
   *******//End of section I'm confused about

            System.out.println(map.toString());
        }
        catch (Exception e){
            e.printStackTrace();
        }
    }
}
Community
  • 1
  • 1
c.timothy
  • 97
  • 10
  • why don't you adapt your question to the least significant? Is that what you are actually interested in _enhanced for loops_? Then you may want to look at: https://docs.oracle.com/javase/tutorial/java/nutsandbolts/for.html – Roland Jan 31 '17 at 12:54
  • You may also want to read the [javadoc from HashMap(int, float)](https://docs.oracle.com/javase/8/docs/api/java/util/HashMap.html#HashMap-int-float-) for the `(50, 10)`. But please, at least try to solve it yourself before looking up solutions. – Roland Jan 31 '17 at 12:59

3 Answers3

3
for (String w : list) {
    Integer i = map.get(w);
    if(i == null) {
        map.put(w, 1);
    }
    else {
        map.put(w, i+1);
    }
}

For every string in the list,
      Get the old value and store it as i.
      IF the string is not yet in the map (i is null), insert 1. (First occurrence)
      OTHERWISE, insert (i + 1) (Add one to the current count.)

A more descriptive rewrite could be

for (String word : list) {                 //For every word in list,
    Integer previousAmount = map.get(word);    //Get the current count and store it.
    if(previousAmount == null)             //If the count doesn't exist (null, not in map),
        map.put(word, 1);                  //Put 1 in the map (first time.)
    else                                   //Otherwise (in the map)
        map.put(word, previousAmount + 1); //Add one to the current amount
}

This also could have simply been written as

for(String w : list)
    map.put(w, map.getOrDefault(w, 0) + 1);
Salem
  • 13,516
  • 4
  • 51
  • 70
  • So 'map.get(word)' looks up the word in the map and stores the count (key) for that word in 'previousAmount' then either increments the count (key) or adds the word to the map with a '1' for the count? Is my thinking right or is the count not the key? – c.timothy Jan 31 '17 at 14:17
  • 1
    @c.timothy `word` is the key, `count` is the value. By using `map.get(word)` you are getting the `Integer` associated with that specific `String`. This is why it is a `HashMap` - `String`s are the keys and `Integer`s are the values. Perhaps you are confusing key and value? – Salem Jan 31 '17 at 15:21
  • Oh okay I understand it I was confusing key and value. So it checks if the String is in the map, if it is it adds 1 to the value, if it isn't it adds the word to the map. – c.timothy Jan 31 '17 at 17:32
  • @c.timothy exactly, you've got it - if this is solved, can you accept this answer? – Salem Jan 31 '17 at 17:46
  • I've marked it as solved. Thankyou for your help I'll go about re-writing it in my own way now that I understand it! – c.timothy Jan 31 '17 at 19:51
1
for (String w : list){
  Integer i = map.get(w);
  if(i == null){
    map.put(w, 1);
  }
  else {
    map.put(w, i+1);
  }
}

If the string (w) is in the HashMap (map.get(w)), then the new string is introduced in the HashMap; otherwise, the string is introduced (again) and the counter is modified (i+1)

Urko Pineda
  • 134
  • 1
  • 3
  • 15
1

I find clear comments help a lot.

    // For each word in the list.
    for (String w : list) {
        // Get it's current count from the Map.
        Integer i = map.get(w);
        if (i == null) {
            // Null means never seen before so it's count becomes 1
            map.put(w, 1);
        } else {
            // Seen this word - add one to the count.
            map.put(w, i + 1);
        }
    }
OldCurmudgeon
  • 64,482
  • 16
  • 119
  • 213