Uzyskanie enum związanego z wartością int

Wcześniej miałem moje enums LegNo zdefiniowane po prostu jako:

NO_LEG, LEG_ONE, LEG_TWO

I wywołując return LegNo.values()[i];, udało mi się uzyskać wartość związaną z każdym enum.

Ale teraz zdecydowałem, że chcę LegNo enum NO_LEG Być int -1 zamiast 0 więc zdecydowałem się użyć prywatnego konstruktora, aby zainicjować i ustawić jego wartość int

NO_LEG(-1), LEG_ONE(1), LEG_TWO(2);

private LegNo(final int leg) { legNo = leg; }

Jedyną rzeczą jest to, że ponieważ robię to w ten sposób metoda values() nie będzie działać dla NO_LEG enum. Jak uzyskać enum związane z int? Czy istnieje jakiś efektywny sposób na zrobienie tego inaczej niż użycie instrukcji case switch lub if-elseif-elseif

Widzę wiele pytań związanych z uzyskaniem wartości int z enum, ale jestem po odwrotnej.

 72
Author: intboolstring, 2012-06-15

8 answers

Edycja sierpień 2018

Dzisiaj zaimplementowałbym to w następujący sposób

public enum LegNo {
    NO_LEG(-1), LEG_ONE(1), LEG_TWO(2);

    private final int value;

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

    public static Optional<LegNo> valueOf(int value) {
        return Arrays.stream(values())
            .filter(legNo -> legNo.value == value)
            .findFirst();
    }
}

Będziesz musiał zachować mapowanie wewnątrz enum.

public enum LegNo {
    NO_LEG(-1), LEG_ONE(1), LEG_TWO(2);

    private int legNo;

    private static Map<Integer, LegNo> map = new HashMap<Integer, LegNo>();

    static {
        for (LegNo legEnum : LegNo.values()) {
            map.put(legEnum.legNo, legEnum);
        }
    }

    private LegNo(final int leg) { legNo = leg; }

    public static LegNo valueOf(int legNo) {
        return map.get(legNo);
    }
}

Blok statyczny zostanie wywołany tylko raz, więc praktycznie nie ma tu problemu z wydajnością.

EDIT: zmieniono nazwę metody na valueOf, ponieważ jest bardziej wbudowana w inne klasy Javy.

 123
Author: adarshr,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-08-28 08:47:37

Możesz również dołączyć statyczną metodę do enum, która iterauje wszystkie elementy i zwraca poprawną.

public enum LegNo {
   NO_LEG(-1),
   LEG_ONE(1),
   LEG_TWO(2);

   private int legIndex;

   private LegNo(int legIndex) { this.legIndex = legIndex; }

   public static LegNo getLeg(int legIndex) {
      for (LegNo l : LegNo.values()) {
          if (l.legIndex == legIndex) return l;
      }
      throw new IllegalArgumentException("Leg not found. Amputated?");
   }
}

Teraz, jeśli chcesz uzyskać wartość Enum przez liczbę całkowitą, po prostu użyj:

int myLegIndex = 1; //expected : LEG_ONE
LegNo myLeg = LegNo.getLeg(myLegIndex);
 19
Author: Mike Adler,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-06-15 10:09:25

Odpowiedź Adarshra dostosowana do Java 8:

import static java.util.Arrays.stream;
import static java.util.stream.Collectors.toMap;

import java.util.Map;

public enum LegNo {
    NO_LEG(-1), LEG_ONE(1), LEG_TWO(2);

    private final int legNo;

    private final static Map<Integer, LegNo> map =
            stream(LegNo.values()).collect(toMap(leg -> leg.legNo, leg -> leg));

    private LegNo(final int leg) {
        legNo = leg;
    }

    public static LegNo valueOf(int legNo) {
        return map.get(legNo);
    }
}
 13
Author: Marcin,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 12:10:35

Można również uzyskać dostęp do wartości Enum odpowiadającej podanej wartości całkowitej po prostu przez wywołanie metody values () na enum LegNo. Powroty pole legno enums: LegNo.values[0]; //returns LEG_NO LegNo.values[1]; //returns LEG_ONE LegNo.values[2]; //returns LEG_TWO

Nie dokładnie tego, czego szukał, ale dość blisko i bardzo prosto. (Chociaż obiekt jest martwy, może być przydatny dla kogoś innego.)
 5
Author: Tadeas,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-03-18 15:36:04

Java 8 way z wartością domyślną:

public enum LegNo {
    NO_LEG(-1), LEG_ONE(1), LEG_TWO(2);

    private final int legNo;

    LegNo(int legNo) {
        this.legNo = legNo;
    }

    public static LegNo find(int legNo, Supplier<? extends LegNo> byDef) {
        return Arrays.asList(LegNo.values()).stream()
                .filter(e -> e.legNo == legNo).findFirst().orElseGet(byDef);
    }
}

Do wywołania:

LegNo res = LegNo.find(0, () -> LegNo.NO_LEG);

Lub z wyjątkiem:

LegNo res = LegNo.find(0, () -> {
    throw new RuntimeException("No found");
});
 5
Author: Dmitry Sokolyuk,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-03-21 11:43:36

Ponieważ twoje enum zawiera tylko 3 elementy, najszybszym sposobem będzie użycie serii if else, tak jak sugerowałeś.

Edit: odpowiedź, którą podał adarshr, lepiej nadaje się do ogólnych przypadków, gdzie jest wiele wartości enum, ale myślę, że jest to przesada dla Twojego problemu.

 1
Author: DieterDP,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-06-15 09:30:35
public enum LegNo {
    NO_LEG(-1), LEG_ONE(1), LEG_TWO(2);

    private int legNo;

    private LegNo(int leg) { legNo = leg; }

    public static LegNo valueOf(int legNo) {
        for (LegNo leg : LegNo.values()) {
            if (leg.legNo == legNo) return leg;
        }   
    }
}

assert LegNo.valueOf(2) == LegNo.LEG_TWO
assert LegNo.valueOf(3) == null
 0
Author: Tom B,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-11-16 04:07:53
public enum body
{
    NO_LEG = 0,         // bit 1
    LEG_ONE = 2,        // bit 2 
    LEG_TWO = 4,        // bit 3 
    NO_ARM = 8,          // bit 4 
    ARM_ONE = 16,  // bit 5 
    ARM_TWO = 32  // bit 6 

}

Użyj go w ten sposób (int)body.LEG_ONE; / / / które zwraca 2

Jest to również bardzo szybkie i łatwe do odczytania, ponieważ odbywa się to w czasie kompilacji.

 -4
Author: Ole Michael Oldhøj,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-06-15 09:24:34