Enum değeri int dönüştürmek nasıl?


240

Bir tür int döndüren bir işlevi var. Ancak, sadece VERGİ numaralandırmasının bir değeri var.

VERGİ numaralandırma değerini bir int'e nasıl aktarabilirim?

public enum TAX {
    NOTAX(0),SALESTAX(10),IMPORTEDTAX(5);

    private int value;
    private TAX(int value){
        this.value = value;
    }
}

TAX var = TAX.NOTAX; // This value will differ

public int getTaxValue()
{
  // what do do here?
  // return (int)var;
}

1
Olası yinelenen enum int maç için nasıl
malat

Yanıtlar:


354

Numaralandırmayı bir valueşekilde ortaya çıkarmanız gerekir, örn.

public enum Tax {
    NONE(0), SALES(10), IMPORT(5);

    private final int value;
    private Tax(int value) {
        this.value = value;
    }

    public int getValue() {
        return value;
    }
}

...

public int getTaxValue() {
    Tax tax = Tax.NONE; // Or whatever
    return tax.getValue();
}

(İsimleri biraz daha geleneksel ve okunabilir olarak değiştirdim, btw.)

Bu, kurucuda atanan değeri istediğinizi varsayar . İstediğiniz bu değilse, bize daha fazla bilgi vermeniz gerekir.


1
@likejiujitsu: Bu ters yöne gidiyor. Bu soruda, OP zaten bir tür değere sahiptirTax ve sayısal değeri ondan almak istiyor.
Jon Skeet

Ben sadece denedim ve myEnumValue = MyEnum.valueOf(myInt);arg türü String olması gerekir başarısız olduğunu fark - ya da eksik bir şey var mı?
likejudo

Bu çözüm hiçbir şeyden daha kötü. Görünüşe göre Java'da numaralandırmalar kullanılmamalıdır? Yoksa JDK 1.8 bunu değiştirdi mi?
ebyrob

@ebyrob: Oylama göz önüne alındığında, benim gibi birçok insan sizinle aynı fikirde değil gibi görünüyor. Sabit bir değer kümesi istiyorsanız, numaralandırmalar kesinlikle iyidir.
Jon Skeet

209

Bunu tercih ederim:

public enum Color {

   White,

   Green,

   Blue,

   Purple,

   Orange,

   Red
}

sonra:

//cast enum to int
int color = Color.Blue.ordinal();

34
Bu yanlıştır / Joshua Bloch tarafından Etkili Java (2. baskı) kitabında önerilmez. Bkz. Madde 31.
user504342

43
@ user504342 Kitabın 2. basımım yok, bu yüzden lütfen bize neden önerilmediğinin özünü verebilir misiniz?
likejudo

17
2 neden: bir, yeni sabitler eklenirse sıra değerleri ve sabitler arasındaki herhangi bir ilişki kırılır ve iki API belgesi buna karşı özellikle tavsiye eder.
jordanpg

8
Çok temiz ve mükemmel. Birkaç "yapma" ve "önerilmez" görüyorum. Neden kötü sayıldığını araştırmam gerekecek. Şişirilmiş örneklerin bazıları kötü IMO'ya benziyor. Bu kadar basit bir işi yapmak için çok fazla çalışma.
Herb Meehan

4
Bir ekipte, ortak geliştiricinizin ortada bir değer ekleyeceğinden (başlangıçta daha kötü) emin olabilirsiniz veya sadece bunları sıralayın çünkü yapacakları bir şeyleri yoktur ve kullanarak kodu tamamen karıştırırlar.ordinal()
Michael Laffargue

18

Yapıcıda atadığınız değerin olmasını istiyorsanız, bu değeri döndürmek için enum tanımına bir yöntem eklemeniz gerekir.

Enum değerini temsil eden benzersiz bir sayı istiyorsanız, kullanabilirsiniz ordinal().


2
Dikkatli ol. ordinal()Geçerli kullanım durumlarından çok daha fazla gelişimsel anti-desen vardır ordinal(). İçin benzersiz bir değer depolamanız gerekiyorsa enum, yalnızca enum. EnumSets, Numaralandırma Listeleri, EnumMaps ve kullanılabilir olmasını isteyebileceğiniz hemen hemen diğer tüm Enum koleksiyonları vardır.
Edwin Buck

1
@EdwinBuck: Bunu belirtmek güzel, sadece varlığından bahsetmek istedim ordinal()çünkü OP aslında int'in ne olmasını istediğini netleştirmedi.
unholysampler

Sıradan olma. Lütfen bununla ilgili enum api'yi kontrol edin. Yukarı oy kaldırıldı.
Hovercraft Eels Eels

3
İnsanların ordinal()içsel olarak sayım içinde kullanımı hakkındaki düşüncelerini merak ediyorum . Mesela ben "adında bir enum var demek Seasondeğerleri içeren" Spring, Summer, Autumn, ve Winter, ve adında bir kamu yöntem vardır next()döndürür values()[(ordinal() + 1) % 4] , hiçbir kod hiç sıra numarası Haricen görür ve bu enum ek üyeler orada olmayacak geçerli bir kullanım durumu gibi görünüyor.
Darrel Hoffman

1
@DarrelHoffman Benim hissim, bunu yapmak iyi, çünkü ordinal()numaralandırma numaralandırma sabitlerindeki değişiklikler nedeniyle kırılma kodunda menteşe kullanılmasına karşı gördüğüm tek güçlü argüman . Numaralandırmanın sabitlerini değiştirecekseniz, zaten bu dosyada olmanız gerekir. Çoğu numaralandırma oldukça kısadır ve eğer değilse, dosyayı daha ayrıntılı bir şekilde kontrol etmelisiniz. Her iki durumda da muhtemelen next()yönteminizi kapsayan bir birim testiniz olmalıdır .
Alan Hensley

12

Bazen C # yaklaşımı Java dünyasında hayatı kolaylaştırır ..:

class XLINK {
static final short PAYLOAD = 102, ACK = 103, PAYLOAD_AND_ACK = 104;
}
//Now is trivial to use it like a C# enum:
int rcv = XLINK.ACK;

Benim için bu en arzu edilen yol. DB dostu bir veri türü olan enum (kod netliği) faydaları alıyorum ve "android yolu" yapmak için 100 enum alternatifleri araştırmak zorunda değilsiniz. Basit ve etkili.
John Ward

Güzel. Java enumunun, bir enumun ne için kullanıldığı gerçeğinden tamamen kopmuş gibi ... özellikle insanlar singleton gibi şeyler için suistimal etmeye başlarlarsa. Bu yaklaşımın dezavantajı vardır, ancak tüm değerleri elde etmenin kolay bir yolu yoktur.
Nyerguds

Bunun bir yönteme enum değeri aktarmaya çalışmanın dezavantajı yok mu? Artık XLINK'i bir yönteme geçiremezsiniz, çünkü somut hiçbir şeyi temsil etmez. Yönteminize yazmayı kaybedersiniz. Yöntem imzasının XLINK yerine kısa olması gerekir.
Dustin Jensen

2

Bir dize temsilini kullanmak bir tamsayıdan daha iyidir, çünkü enum'a değerler eklenirse Dize hala geçerlidir. Enum değerini bir String'e dönüştürmek için enum name () yöntemini ve Dize'den bir enum temsili oluşturmak için enum's valueOf () yöntemini kullanabilirsiniz. Aşağıdaki örnek, enum değerinin String ve back'e nasıl dönüştürüleceğini gösterir (ValueType bir enumdur):

ValueType expected = ValueType.FLOAT;
String value = expected.name();

System.out.println("Name value: " + value);

ValueType actual = ValueType.valueOf(value);

if(expected.equals(actual)) System.out.println("Values are equal");

1
public enum Tax {

NONE(1), SALES(2), IMPORT(3);

private final int value;
    private Tax(int value) {
        this.value = value;
    }

    public String toString() {
        return Integer.toString(value);
    }
}

class Test {
    System.out.println(Tax.NONE);    //Just an example.
}

0

Biraz farklı bir yaklaşım (en azından Android'de) bir dizi int sabitini birleştirmek için IntDef ek açıklamasını kullanmaktır

@IntDef({NOTAX, SALESTAX, IMPORTEDTAX})
@interface TAX {}
int NOTAX = 0;
int SALESTAX = 10;
int IMPORTEDTAX = 5;

İşlev parametresi olarak kullanın:

void computeTax(@TAX int taxPercentage){...} 

veya değişken bildirimde:

@TAX int currentTax = IMPORTEDTAX;
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.