the_prole
the_prole

Reputation: 8945

How to map enums to integers implicitliy

I know I'm not using the right jargon, but basically I want to take this code in C++ and port it over to Java

public enum Packets {

    // Maps enums to integers 0-3
    PACKET_NONE = 0, PACKET_SYNC, 
    PACKET_EXPECT_TO_RECEIVE, PACKET_AVAIL_1, 

    // Maps enums to integers 13-16
    PACKET_FILL = 13,  PACKET_GLASS, PACKET_FILLi, PACKET_GLASSi
}

I want to explicitly map an enum to an int, and then have every subsequent enum implicitly map to the next increment of that integer (or some solution as close to this C code as possible).

Upvotes: 1

Views: 140

Answers (3)

Sharjeel
Sharjeel

Reputation: 15798

In Java you can assign values to Enum if that's what you are looking for. It will look like this:

public enum Packets {
    PACKET_NONE(0),
    PACKET_SYNC(1),
    PACKET_EXPECT_TO_RECEIVE(2),
    PACKET_AVAIL_1(3);

    private int value;

    Packets(int value){
        this.value = value;
    }

    public int getValue(){
        return value;
    }
}

Now you can call enum like this to get it's value:

Packets.PACKET_SYNC.getValue(); //It will return 1

Upvotes: 4

Alex
Alex

Reputation: 827

This is not that clean of a solution but if you really want to auto-initialize them to increment the same way the C++ declaration does, without explicitly defining each individual ID, you can do something like this:

public enum Packets
{
    PACKET_NONE(0),
    PACKET_SYNC(1),
    PACKET_EXPECT_TO_RECEIVE(2),
    PACKET_AVAIL_1(3),
    PACKET_FILL(13),
    PACKET_GLASS(),
    PACKET_FILLI(),
    PACKET_GLASSI();

    private int id;

    private Packets(int id) {
        this.id = id;
    }

    private Packets(){
        this.id = -1;
    }

    public final int getId() {
        return id;
    }

    public void setId(int id){
        this.id = id;
    }

    public static void initIds(){
        for(Packets p : Packets.values()){
            if(p.getId()==-1){
                if(p.ordinal()==0){
                    p.setId(0);
                }else{
                    p.setId(Packets.values()[p.ordinal()-1].getId()+1);
                }
            }
        }
    }
}

Then you call the initialize and it will fill in the ID's for you:

Packets.initIds();
System.out.println(Packets.PACKET_AVAIL_1.getId()); //3
System.out.println(Packets.PACKET_GLASS.getId()); //13
System.out.println(Packets.PACKET_FILL.getId()); //14
System.out.println(Packets.PACKET_FILLI.getId()); //15

edit/addition:

If you move the code from the initIds()method into a static initializer block, you do not need the initialize call somewhere in your code:

public enum Packets {
    PACKET_NONE(0),
    PACKET_SYNC(1),
    PACKET_EXPECT_TO_RECEIVE(2),
    PACKET_AVAIL_1(3),
    PACKET_FILL(13),
    PACKET_GLASS(),
    PACKET_FILLI(),
    PACKET_GLASSI();

    static {
        for (Packets p : Packets.values()) {
            if (p.getId() == -1) {
                if (p.ordinal() == 0) {
                    p.setId(0);
                } else {
                    p.setId(Packets.values()[p.ordinal() - 1].getId() + 1);
                }
            }
        }
    }

    private int id;

    private Packets(int id) {
        this.id = id;
    }

    private Packets() {
        this.id = -1;
    }

    public final int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }
}

Upvotes: 2

Björn Zurmaar
Björn Zurmaar

Reputation: 829

You can add a field to your enum, intialize this field in the enumeration constant's constructor call and then return this field from a public getter. This should look about like this:

public enum Packets
{
    PACKET_NONE(0),
    PACKET_SYNC(1),
    PACKET_EXPECT_TO_RECEIVE(2),
    PACKET_AVAIL_1(3),
    PACKET_FILL(13),
    PACKET_GLASS(14),
    PACKET_FILLI(15),
    PACKET_GLASSI(16);

    private final int id;

    private MyEnum(final int id) {
        this.id = id;
    }

    public final int getId() {
        return index;
    }
}

Upvotes: 2

Related Questions