Search code examples
javaconstructornullpointerexceptionlinkedhashmap

How can I print a LinkedHashMap of <Object, Integer>?


So I have a class Spaceship with some private variables, one of which have a LinkedHashMap of another Class and an Integer like this

private LinkedHashMap<Resource, Integer> cargo;

Resource is an Abstract class that has several types of Resources (like ResourceBlue, ResourceRed, etc...)

Can I do a LinkedHashMap with an abstract class and if so, how would I go about to do it?

This is what I have so far:

Constructor:

public SpaceShip() {

    this.cargoHold = 0;
    this.upgradeLevel = 0;
    this.drone = null;
    this.artifact = 0;
    this.crewMembers = new ArrayList<String>() {
        {
            add("Captain");
            add("Navigation");
            add("Landing");
            add("Shields");
            add("Cargo");
        }
    };
    this.cargo = new LinkedHashMap<Resource, Integer>(){
        {
            cargo.putIfAbsent(new ResourceAzul(), 0);
            cargo.putIfAbsent(new ResourcePreto(), 0);
            cargo.putIfAbsent(new ResourceVerde(), 0);
            cargo.putIfAbsent(new ResourceVermelho(), 0);
        }
    };

}

When I run this in my main (as a test):

SpaceShip ss = new SpaceShip();
System.out.println(ss);

This is just giving me a NullPointerException at the first "putIfAbsent" in the constructor.


Solution

  • What you're doing with that shorthand is actually rather complex. You're creating an anonymous subclass of LinkedHashMap containing a non-static block. That non-static block, similar to a constructor, will be run during the objects instantiation. Because your object hasn't yet been instantiated, your "cargo" variable will not exist. In a non-static block, similarly to a constructor, you can use the "this" keyword.

    this.cargo = new LinkedHashMap<Resource, Integer>(){
        {
            this.put(new ResourceAzul(), 0);
            this.put(new ResourcePreto(), 0);
            this.put(new ResourceVerde(), 0);
            this.put(new ResourceVermelho(), 0);
        }
    };
    

    Also, because your cargo LinkedHashMap is just being created, it will be empty. So you can simplify "putIfAbsent" to just "put".