简体   繁体   中英

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.

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".

You can't put objects into cargo until you complete the initialization statement. The putIfAbsent() calls should come after:

 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);

You have multiple questions in your actual questions. To answer the question of how to print the contents of the LinkedHashMap, you can print it normally to System.out.println(this.cargo) , but you will need to @Override the toString() method for each of your Resource objects. Otherwise, calling toString() on them will, by default, just print the class name and memory reference.

If you want to use this style of initialization don't write cargo. in front of all the putIfAbsent() calls. cargo is still null at this point.

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

This matches how you just wrote add() rather than crewMembers.add() above.

Also, seeing as this is a brand new map it'd be simpler to just call put() . You know the map is starting out empty, no need for putIfAbsent() .

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM