Search code examples
javanullpointerexceptionhashmapiteration

Java Foreach Loop through Hashmap Throwing NPE -- What might the problem here be?


As part of a project, I've been tasked with creating a method that outputs a List of the most commonly occurring Strings in a given input List. The assignment specifies that this must be done by creating a hashmap of words (Strings) and the number of times they appear (Integers.) Then, the ones that appear most often must be returned in a List.

When I tried to run my implementation of this, I got the following error: java.lang.NullPointerException: Cannot invoke "java.lang.Integer.intValue()" because the return value of "java.util.Iterator.next()" is null

public SList commonStrings() {
        HashMap<String, Integer> frequencies = new HashMap<String, Integer>(this.size());
        int numOfMostCommon = 0;
        int highest = 0;
        int j = 0;
        for (int i = 0; i < this.size(); i++) {
            if (frequencies.containsKey(this.backingArray[i])) {
                frequencies.replace(this.backingArray[i], frequencies.get(backingArray[i]+1));
            }
            else {
                frequencies.put(this.backingArray[i], 1);
            }
        }
        for (int i : frequencies.values()) {
           if (i > highest) {
                highest = i;
            }
        }
        for (int i : frequencies.values()) {
           if (i == highest) {
                numOfMostCommon++;
            }
        }
        String[] mostCommon = new String[numOfMostCommon];
        for (Map.Entry<String,Integer> i : frequencies.entrySet()) {
            if (i.getValue() == highest) {
                mostCommon[j] = i.getKey();
                j++;
            }
        }
        return new SListArray(mostCommon);
        }

Solution

  • A typo. You wrote:

    frequencies.get(backingArray[i]+1)
    

    You wanted:

    frequencies.get(backingArray[i])+1
    

    The former gets the value associated with something else, which is likely non-existent, thus, gets you null, thus, replaces the value associated with backingArray[i] with null. Which you later get, resulting in a NullpointerException`.

    The second form simply 'adds 1 to the value' which is presumably what you want.

    Note that you can do this in a single operation with merge, but, that's not going to meaningfully change any performance here - it would just be arguably easier to read.