2

Scenario

I've got enums

UNDEFINED(-1),
FIS(0),
MANUELL(1)

defined as

public enum Ausloesungsart { UNDEFINED( -1), FIS( 0), MANUELL( 1); }

however at runtime i'm adding another enum if it's not contained in the list as UNDEFINED with the parsed code, as in 123.

Here is how I take the Enum:

public static Ausloesungsart fromIdentifier(Integer code) {

        if (enumsByIdentifier.containsKey(code)) {
            return enumsByIdentifier.get(code);
        } else {
            enumsByIdentifier.put(code, Ausloesungsart.UNDEFINED);
            return enumsByIdentifier.get(code);
        }
    }

by now the list should contain

UNDEFINED(-1),
FIS(0),
MANUELL(1),
UNDEFINED(123)

when parsing the file it obviously sets the value 88 and searches for it. However it returns -1 in the end on the frontend.

Notice

It never even jumps into the else clausel, somehow it's already in?

Any idea what I'm missing?

Edit:

Where the parsing happens:

Ausloesung ausloesung = new Ausloesung(Ausloesungsart.fromIdentifier(header.getReleaseType()));

at this point, releaseType is 123

but in the end there is -1 = Undefined instead of

123 = Undefined

in the database and frontend.

Usecase:

Any Status not in the enumeration should be displayed in the frontend as in <CODE> = Undefined

Currently the message is built with a property attribute:

my.properties:

Ausloesungsart.UNDEFINED= {0} \= Unbekannt
Ausloesungsart.FIS=0 \= FIS
Ausloesungsart.MANUELL=1 \= Manuell
0x45
  • 779
  • 3
  • 7
  • 26
  • that enum is declared under the name ***Ausloesungsart*** ??? right? – ΦXocę 웃 Пepeúpa ツ Aug 23 '17 at 12:45
  • 1
    Sorry... missed it! `public enum Ausloesungsart { UNDEFINED( -1), FIS( 0), MANUELL( 1); }` @ΦXocę웃Пepeúpaツ Edit: `enumsByIdentifier.put(code, Ausloesungsart.UNDEFINED);` or what exactly do you mean, the added enum is also of type `Ausloesungsart` – 0x45 Aug 23 '17 at 12:46
  • your are putting values in the map and that is working... what you will never get to work is that you return a enum with that integer attribute... – ΦXocę 웃 Пepeúpa ツ Aug 23 '17 at 12:53
  • I don't think enums are mutable... so you could never change the enum at runtime... which means, your return value is correctly -1. You might want to read this: https://stackoverflow.com/questions/20168502/changing-enum-at-runtime-java – Faheem Aug 23 '17 at 12:54
  • There is just one single instance UNDEFINED with code -1. Never 88. But tenumsByIdentifer will hold a mapping from 88 to UNDEFINED(-1). – Joop Eggen Aug 23 '17 at 12:55

3 Answers3

1

however at runtime i'm adding another enum if it's not contained in the list as UNDEFINED with the parsed code, as in 123.

Enums are designed to represent immutable things.
You cannot add a new enum value at runtime and you should not try to modify the actual either.

However it returns -1 in the end on the frontend.

Associating an integer value to an enum value in a map will not modify the state of the enum itself.
If multiple integer values may be associated to UNDEFINED enum value and that these integer values are not specified at compile time, you should probably not use the enum field to set this information.

It doesn't mean that the UNDEFINED enum could not be associated to multiple numeric values. But this should not done directly in the state itself of the enum values.
You could use a custom class that provides the two information : the String placeholder and the numeric code.
You could introduce a static method in Ausloesungsart that returns it.

public static getAusloesungsartWithValue(Integer code){
   for (Ausloesungsart current : values()){
      if (current.numericValue.equals(code)){
         return new AusloesungsartWithValue(current, code);
      }
   }

    return new AusloesungsartWithValue(UNDEFINED, code);
}

Then call it :

AusloesungsartWithValue value = Ausloesungsart.getAusloesungsartWithValue(123); // UNDEFINED
AusloesungsartWithValue otherValue = Ausloesungsart.getAusloesungsartWithValue(0); // FIS
davidxxx
  • 125,838
  • 23
  • 214
  • 215
  • Enum to define enum values yes but the numeric value associated to each one : `-1, 1, 0` should be constant – davidxxx Aug 23 '17 at 12:59
  • Puh, this would change a lot in my architecture... isn't there any way to access the newly created enum by value? – 0x45 Aug 23 '17 at 13:00
  • You **cannot** create a new enum value at runtime. I am sorry for you but without doing it your architecture is flawed and things will probably become worst. To not break too much the client code, you may introduce a class that will contain both the enum and the numeric value associated to. It could have a constructor such as `MyClassWithEnum(Ausloesungsart enum, Integer value)`. Then provide to this class the same API that the enum value and it should be not so bad. – davidxxx Aug 23 '17 at 13:05
  • edited my question with the use case, what's your opinion? – 0x45 Aug 23 '17 at 13:11
  • It changes nothing to the problem. I edited to illustrate what I said in my comment. – davidxxx Aug 23 '17 at 13:24
  • Thanks... feels Bad to take over existing projects, so basically this is just a workaround and the architecture is already messed up? – 0x45 Aug 23 '17 at 13:28
  • With this way, the design is rather OK. The wrapper class provides the flexibility at runtime as enum constants cannot provide. – davidxxx Aug 23 '17 at 13:39
0

What do you mean "it returns -1 in the end on the frontend". You probably implemented it is like this:

enum Ausloesungsart {
    UNDEFINED(-1),
    FIS(0),
    MANUELL(1);

    private int value;
    public void getValue() { return value; }
}

Now you can put these enum items into maps all you want, its value will never change.

To display the list you mention in your comment to this answer, do

for (int value : yourList) {
    Ausloesungsart art = Arrays.stream(Ausloesungsart.values())
        .filter(a -> a.getValue() == value)
        .findFirst().orElse(Ausloesungsart.UNDEFINED);
    System.out.println(String.format("<%d>: %s", value, art.toString());
}
daniu
  • 14,137
  • 4
  • 32
  • 53
  • So there is no chance in accessing `UNDEFINED(88)`? – 0x45 Aug 23 '17 at 12:58
  • @0x45 sorry, the UNDEFINED(88) slipped in there unnoticed by me; that is not even valid. Only one UNDEFINED value may be in the enum. I deleted the 88 one from my answer. – daniu Aug 23 '17 at 13:02
  • And is overwriting working, since this would work for my use case – 0x45 Aug 23 '17 at 13:03
  • @0x45 I don't know what you mean by overwriting in this context; you could of course add a setValue(). However, that would break the code for undefined in the places it is used. You should probably state the exact use case you're trying to implement, because it looks like what you're trying is simply conceptually wrong. – daniu Aug 23 '17 at 13:07
  • Use case is: Any status not in the Enumeration should be displayed as `" = Undefined"` at the frontend – 0x45 Aug 23 '17 at 13:10
  • @0x45 It's not clear where you get the list of status codes from. I added a short piece of code that should do it. – daniu Aug 23 '17 at 13:15
0

your are putting values in the map and that is working... what you will never get to work is that you return a enum with that integer attribute...

your method is doing insertiong in a Map

so you can at the end have something like

UNDEFINED(-1),
FIS(0),
MANUELL(1),
UNDEFINED(123),
UNDEFINED(1231),
UNDEFINED(12311),
UNDEFINED(1233123),

but all those calues are still the same enum: Ausloesungsart.UNDEFINED

no matter how much the map changes, you have at the end the same enum

public enum Ausloesungsart { UNDEFINED( -1), FIS( 0), MANUELL( 1); }
ΦXocę 웃 Пepeúpa ツ
  • 47,427
  • 17
  • 69
  • 97