วิธีแปลงค่า enum เป็น int


240

ฉันมีฟังก์ชั่นที่คืนค่า int อย่างไรก็ตามฉันมีค่าการแจงนับ TAX เท่านั้น

ฉันจะส่งค่าการแจงนับ TAX ไปยัง int ได้อย่างไร

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
เป็นไปได้ที่ซ้ำกันของวิธีจับคู่ int กับ enum
malat

คำตอบ:


354

คุณต้องทำให้ enum แสดงvalueอย่างใดเช่น

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();
}

(ฉันเปลี่ยนชื่อเป็นแบบธรรมดาและอ่านได้ง่ายขึ้นเล็กน้อย)

นี่คือสมมติว่าคุณต้องการค่าที่กำหนดในตัวสร้าง หากนั่นไม่ใช่สิ่งที่คุณต้องการคุณจะต้องให้ข้อมูลเพิ่มเติมแก่เรา


1
@ likejiujitsu: มันกำลังไปในทิศทางตรงกันข้าม ในคำถามนี้ OP มีค่าประเภทTaxแล้วและต้องการรับค่าตัวเลขจากมัน
Jon Skeet

ฉันแค่ลองมันและรู้ว่ามันล้มเหลวmyEnumValue = MyEnum.valueOf(myInt);ในการหาเรื่องต้องเป็นสตริงประเภท - หรือมีบางสิ่งที่ฉันขาดหายไป?
likejudo

ทางออกนี้แย่กว่าไม่มีอะไรเลย ดูเหมือน Enums ใน Java ไม่ควรใช้ใช่ไหม หรือ JDK 1.8 มีการเปลี่ยนแปลงหรือไม่
ebyrob

@ebyrob: จากการลงคะแนนดูเหมือนว่าหลายคนไม่เห็นด้วยกับคุณอย่างที่ฉันทำ หากคุณต้องการชุดของค่าคงที่จำนวน Enums ก็ดี
Jon Skeet

209

ฉันชอบสิ่งนี้:

public enum Color {

   White,

   Green,

   Blue,

   Purple,

   Orange,

   Red
}

แล้ว:

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

34
สิ่งนี้ไม่ถูกต้อง / ไม่แนะนำโดย Joshua Bloch ในหนังสือของเขา Java ที่มีประสิทธิภาพ (ฉบับที่ 2) ดูรายการ 31.
user504342

43
@ user504342 ฉันไม่มีหนังสือฉบับที่ 2 ดังนั้นคุณสามารถช่วยให้เรามีส่วนสำคัญว่าทำไมจึงไม่แนะนำ?
likejudo

17
2 เหตุผล: หนึ่งการเชื่อมโยงใด ๆ ระหว่างค่าลำดับและค่าคงที่จะแตกถ้ามีการเพิ่มค่าคงที่ใหม่และเอกสาร API สองรายการแนะนำเป็นการเฉพาะ
jordanpg

8
สะอาดและสมบูรณ์แบบมาก ฉันเห็นบางอย่าง "ไม่ทำ" และ "ไม่แนะนำ" ฉันจะต้องค้นคว้าเกี่ยวกับสาเหตุที่ถือว่าไม่ดี ตัวอย่างที่ป่องบางส่วนดูไม่ดี IMO งานมากมายที่ต้องทำเช่นงานง่าย ๆ
สมุนไพรฮัน

4
ในทีมคุณค่อนข้างมั่นใจในการร่วมพัฒนาของคุณจะเพิ่มค่ากลาง (แย่กว่าที่จุดเริ่มต้น) หรือเพียงแค่เรียงพวกเขาเพราะพวกเขาไม่มีอะไรจะทำและระเบียบรหัสโดยใช้.ordinal()
Michael Laffargue

18

ถ้าคุณต้องการค่าที่คุณกำหนดในนวกรรมิกคุณต้องเพิ่มเมธอดในนิยาม enum เพื่อส่งคืนค่านั้น

หากคุณต้องการเป็นจำนวนที่ไม่ซ้ำกันที่เป็นตัวแทนของ enum ordinal()ค่าที่คุณสามารถใช้


2
ระวัง. มีหลายพัฒนาการต่อต้านรูปแบบที่พึ่งพามีกว่ากรณีการใช้งานที่ถูกต้องสำหรับordinal() ordinal()หากคุณจำเป็นต้องเก็บค่าไม่ซ้ำกันสำหรับแล้วก็เก็บenum enumมี EnumSets, รายการ Enums, EnumMaps และเกือบทุกคอลเลกชัน Enum อื่น ๆ ที่คุณอาจต้องการ
Edwin Buck

1
@EdwinBuck: เป็นสิ่งที่ดีที่จะชี้ให้เห็นฉันแค่อยากจะพูดถึงการดำรงอยู่ของordinal()เพราะ OP ไม่ได้ทำให้ชัดเจนว่าสิ่งที่เขาต้องการ int เป็นจริง
unholysampler

ไม่ได้ลำดับ โปรดตรวจสอบ enum api เกี่ยวกับเรื่องนี้ ลบโหวตแล้ว
Hovercraft เต็มของปลาไหล

3
ฉันสงสัยว่าความคิดของผู้คนเป็นอย่างไรเกี่ยวกับการใช้ordinal()ภายในภายในตัวเอง ตัวอย่างเช่นสมมติว่าผมมี enum ที่เรียกว่า " Season" ซึ่งมีค่าSpring, Summer, AutumnและWinterและจะมีวิธีการที่ประชาชนเรียกว่าnext()ซึ่งผลตอบแทนvalues()[(ordinal() + 1) % 4] ภายนอกรหัสไม่เคยเห็นเลขลำดับและจะไม่มีสมาชิกเพิ่มเติมใน enum นี้ ดังนั้นจึงดูเหมือนว่าเป็นกรณีใช้งานที่ถูกต้อง
Darrel Hoffman

1
@DollHoffman ความรู้สึกของฉันคือการทำเช่นนั้นดีเนื่องจากข้อโต้แย้งที่แข็งแกร่งเพียงอย่างเดียวที่ฉันเห็นกับการใช้ordinal()บานพับบนรหัสที่กว้างไกลถูกทำลายโดยการเปลี่ยนแปลงค่าคงที่การแจงนับ enum หากคุณกำลังจะแก้ไขค่าคงที่ของ enum คุณจะต้องอยู่ในไฟล์นั้นแล้ว enums ส่วนใหญ่ค่อนข้างสั้นและถ้าไม่ใช่คุณควรตรวจสอบไฟล์อย่างละเอียดยิ่งขึ้น ในทั้งสองกรณีคุณควรทดสอบหน่วยที่ครอบคลุมnext()วิธีการของคุณอยู่ดี
Alan Hensley

12

บางครั้งวิธี C # ทำให้ชีวิตง่ายขึ้นในโลก Java .. :

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;

สำหรับฉันนี่เป็นวิธีที่ดีที่สุดที่จะไป ฉันได้รับประโยชน์จาก enum (ความชัดเจนของรหัส) ซึ่งเป็นชนิดข้อมูลที่เป็นมิตรกับฐานข้อมูลและฉันไม่จำเป็นต้องวิจัยทางเลือก 100 enum เพื่อทำ "วิธี Android" ง่ายและมีประสิทธิภาพ
John Ward

ดี มันเหมือนกับว่า java enum ถูกตัดการเชื่อมต่ออย่างสมบูรณ์จากความเป็นจริงของสิ่งที่ enum ใช้สำหรับ ... โดยเฉพาะอย่างยิ่งถ้าผู้คนเริ่มใช้มันเพื่อสิ่งต่าง ๆ เช่น singletons วิธีการนี้มีข้อเสียคือไม่มีวิธีง่าย ๆ ในการรับค่าทั้งหมด
Nyerguds

นี่ไม่ใช่ข้อเสียของการพยายามส่งผ่านค่า enum ไปยังวิธีการหรือไม่ คุณไม่สามารถส่งผ่าน XLINK ไปยังวิธีการได้อีกต่อไปเพราะมันไม่ได้แสดงถึงรูปธรรมใด ๆ คุณสูญเสียการพิมพ์ในวิธีการของคุณ ลายเซ็นเมธอดจะต้องอ่านแบบย่อแทน XLINK
ดัสตินเจนเซ่น

2

อาจจะเป็นการดีกว่าถ้าใช้การแสดงสตริงกว่าจำนวนเต็มเนื่องจากสตริงยังคงใช้ได้หากเพิ่มค่าลงใน enum คุณสามารถใช้วิธีชื่อ enum () เพื่อแปลงค่า enum เป็น String เป็นวิธี valueOf () ของ enum เพื่อสร้างการเป็นตัวแทน enum จาก String อีกครั้ง ตัวอย่างต่อไปนี้แสดงวิธีการแปลงค่า enum เป็น String และ back (ValueType คือ enum):

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

แนวทางที่แตกต่างออกไป (อย่างน้อยบน Android) คือการใช้ คำอธิบายประกอบIntDefเพื่อรวมชุดของค่าคงที่ int

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

ใช้เป็นพารามิเตอร์ฟังก์ชัน:

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

หรือในการประกาศตัวแปร:

@TAX int currentTax = IMPORTEDTAX;
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.