justkevin
justkevin

Reputation: 3199

What's wrong with this enum lookup map?

I have an enum where the reverse-lookup table I created for it returns null for all values. I added an assert after the lookup table is created, and sure enough, it's empty. I feel like this is something simple and obvious that I'm overlooking because I use this exact same structure for all my enums and they work fine.

public enum TerrainType {
ROAD(1),
PLAINS(2),
FOREST(3),
MOUNTAINS(4);

private static final Map<Byte,TerrainType> lookup = new HashMap<Byte,TerrainType>();

private final byte terrainId;

static {
    for(TerrainType type : EnumSet.allOf(TerrainType.class)) {
        lookup.put(type.getByte(),type);
    }
    assert lookup.get(1) != null; // <--- THIS ASSERT FIRES, WHY?
} 

TerrainType(int id) {
    assert id > 0 && id < 128: "ID must be from 1 to 127"; 
    this.terrainId = (byte) id;
}

public static TerrainType get(int id) {
    return lookup.get(id);
}

public byte getByte() {
    return this.terrainId;
}
}

Upvotes: 1

Views: 307

Answers (3)

Kal
Kal

Reputation: 24910

The literal 1 is an integer.

This works.

assert lookup.get(Integer.valueOf(1).byteValue()) != null

Alternatively, you could change your terrainId to be of type int

Upvotes: 3

Hendra Jaya
Hendra Jaya

Reputation: 1628

Basically it's equals(Object) problem.

Quoting Java API:

"if this map contains a mapping from a key k to a value v such that (key==null ? k==null : key.equals(k)), then this method returns v; otherwise it returns null"

Try this piece of code:

int a = 1;
byte b = (byte) a;
Byte c = b;
boolean d = c.equals(1);
System.out.println(d);

Upvotes: 0

duffymo
duffymo

Reputation: 308848

This works fine for me. Note the changes.

I'd recommend not using assert to enforce your contract. Throw an IllegalArgumentException if you get unexpected input.

import java.util.EnumSet;
import java.util.HashMap;
import java.util.Map;

public enum TerrainType
{
    ROAD(1),
    PLAINS(2),
    FOREST(3),
    MOUNTAINS(4);

    private static final Map<Integer, TerrainType> lookup = new HashMap<Integer, TerrainType>();

    private final int terrainId;

    static
    {
        for (TerrainType type : EnumSet.allOf(TerrainType.class))
        {
            lookup.put(type.getTerrainId(), type);
        }
        assert lookup.get(1) != null; // <--- THIS ASSERT FIRES, WHY?
    }

    TerrainType(int id)
    {
        assert id > 0 && id < 128 : "ID must be from 1 to 127";
        this.terrainId = id;
    }

    public static TerrainType lookupById(int id)
    {
        return lookup.get(id);
    }

    public int getTerrainId()
    {
        return this.terrainId;
    }
}

class TerrainTypeDriver {
    public static void main(String[] args)
    {
        for (int i = 0; i < 6; ++i) {
            System.out.println(TerrainType.lookupById(i));
        }
    }
}

Upvotes: 0

Related Questions