Java HashMap get method null pointer exception

2020-02-26 05:14发布

问题:

I have code similar to the following :-

class A
{
  private HashMap<Character, Boolean> myMap;
  public A()
  {
    myMap = new HashMap<Character, Boolean>();
    String mychars = "asdfzxcvqwer";
    for ( char c : mychars.toCharArray() )
        myMap.put(c, true);
  }
  public doo(String input)
  {
    StringBuilder output = new StringBuilder();
    for ( char c : input.toCharArray() )
    {
      if ( myMap.get(c) )
         output.append(c);
    }
  }
  ...
  ...
}

I get a null pointer exception at the line if ( myMap.get(c) ) -- What am I doing wrong?

回答1:

If c is not contained in myMap, it will return null, which can't be unboxed as a boolean.

Try :

Boolean b = myMap.get(c);
if(b != null && b){
...


回答2:

If myMap doesn't contain a key that matches c, then myMap.get(c) will return null. In that case, when the JVM unboxes what it expects to be a java.lang.Boolean object into a boolean primitive to execute the condition, it founds a null object and therefore throws a java.lang.NullPointerException.

The following block is equivalent to what you have in your example and should make it easier to understand why you would have a NullPointerException:

if (((Boolean) myMap.get(c)).booleanValue()) 

I would re-write your original condition as:

if ( myMap.containsKey(c) )

I hope this helps.



回答3:

Change

if ( myMap.get(c) )

to

if ( myMap.containsKey(c) && myMap.get(c))


回答4:

If there is no entity with required Character in map, then map.get(key) returns null and inside if statement it leads to NullPointerException throwing.



回答5:

A stab in the dark: is there an entry in your map for the particular character assigned to c? If there isn't, Java may be trying to unbox a null value...



回答6:

Changing this

for ( char c : input.toCharArray() )
{
  if ( myMap.get(c) )
     output.append(c);
}

For this

for ( char c : input.toCharArray() )
{
  if ( myMap.containsKey(c) )
     output.append(c);
}

Will make use of the map's defined method to check if a certain key is registered on the map. I'm leaving the for as it is, since you seem to want to check for a group of keys.

myMap.get(c) returns the value associated with that key, or null if the key is not registered.

As a side note, remember that if you use this method with custom objects you'll have to redefine the hashcode and equals methods.

Suggestion: I'm just suggesting this out of a remote idea I have, if it's not a correct interpretation of your code just ignore it. If your map only contains a boolean value to determine if certain value "is contained" or not, I strongly suggest you use a HashSet instead because a map is not doing any sense in that context.



回答7:

Your code is very messy.

  • do is a reserved keyword, do not use it as a method name.
  • a 'if' expression must return a boolean, not null.
  • myMap's initialization is not correctly written

Here is a working version :

import java.util.HashMap;

public class A {
    private HashMap<Character, Boolean> myMap;

    public A() {
        this.myMap = new HashMap<Character, Boolean>();
        String mychars = "asdfzxcvqwer";
        for ( char c : mychars.toCharArray() )
            myMap.put(c, true);
    }

    public String execute(String input) {
        StringBuilder output = new StringBuilder();
        for ( char c : input.toCharArray() )
        {
            if ( this.myMap.get(c) != null )
                output.append(c);
        }
        return output.toString();
    }


    public static void main(String[] args) {
        A test = new A();
        test.execute("abc");
    }
}