[java] تحويل من التعداد الترتيبي إلى التعداد النوع



Answers

هذه بالتأكيد فكرة سيئة . ومن المؤكد أنه إذا استمر الترتيبي فعليًا (على سبيل المثال ، لأن شخصًا ما قام بتأشير عنوان URL) - فهذا يعني أنه يجب عليك دائمًا الحفاظ على ترتيب enum في المستقبل ، وهو ما قد لا يكون واضحًا لرموز التعليمات البرمجية أسفل الخط.

لماذا لا ترميز enum باستخدام myEnumValue.name() (وفك شفرة عن طريق ReportTypeEnum.valueOf(s) ) بدلا من ذلك؟

Question

لدي نوع التعداد ReportTypeEnum الذي يتم تمريره بين الطرق في كل ReportTypeEnum لكنني في حاجة إلى تمرير ذلك على عنوان URL لذلك أستخدم الطريقة الترتيبية للحصول على القيمة int. بعد أن أحصل عليه في صفحة JSP الأخرى الخاصة بي ، أحتاج إلى تحويله مرة أخرى إلى ReportTypeEnum حتى أتمكن من الاستمرار في تمريره.

كيف يمكنني تحويل الترتيبي إلى ReportTypeEnum ؟

باستخدام جافا 6 SE.




هذا ما أستخدمه. أنا لا أدعي أنه أقل فعالية بكثير من الحلول المبسطة أعلاه. ما يفعله هو توفير رسالة استثناء أكثر وضوحاً من "ArrayIndexOutOfBounds" عند استخدام قيمة ترتيبي غير صالح في الحل أعلاه.

فإنه يستخدم حقيقة أن يحدد EnumSet javadoc the iterator بإرجاع العناصر في ترتيبها الطبيعي. هناك تأكيد ما إذا كان هذا غير صحيح.

يوضح اختبار JUnit4 كيف يتم استخدامه.

 /**
 * convert ordinal to Enum
 * @param clzz may not be null
 * @param ordinal
 * @return e with e.ordinal( ) == ordinal
 * @throws IllegalArgumentException if ordinal out of range
 */
public static <E extends Enum<E> > E lookupEnum(Class<E> clzz, int ordinal) {
    EnumSet<E> set = EnumSet.allOf(clzz);
    if (ordinal < set.size()) {
        Iterator<E> iter = set.iterator();
        for (int i = 0; i < ordinal; i++) {
            iter.next();
        }
        E rval = iter.next();
        assert(rval.ordinal() == ordinal);
        return rval;
    }
    throw new IllegalArgumentException("Invalid value " + ordinal + " for " + clzz.getName( ) + ", must be < " + set.size());
}

@Test
public void lookupTest( ) {
    java.util.concurrent.TimeUnit tu = lookupEnum(TimeUnit.class, 3);
    System.out.println(tu);
}



افترض أن لديك التعداد التالي:

public enum ErrorCodes {
    BUSINESS_ERROR(100), SERVER_ERROR(500), NETWORK_ERROR(1000);
}

بشكل افتراضي ، لن تتمكن من استرداد مثيل ErrorCode من خلال قيمته الرقمية حيث أن java لا توفر أي طريقة لاسترداد تعداد Enum بواسطة حقل.

من أجل القيام بذلك ، عادةً ما أقوم بعرض hashmap ثابت داخل فئة Enum الذي يعيّن كل قيمة إلى مثيل Enum المقابل لها كما يلي:

public enum ErrorCodes {
    BUSINESS_ERROR(100), SERVER_ERROR(500), NETWORK_ERROR(1000);

    private int errorCode;
    private static Map<Integer, ErrorCodes> errorCodeByErrorNumber = new HashMap<Integer, ErrorCodes>();

    static {
        for (ErrorCodes errorCode : ErrorCodes.values()) {
            errorCodeByErrorNumber.put(errorCode.getErrorCode(), errorCode);
        }
    }

    private ErrorCodes(int errorCode) {
        this.errorCode = errorCode;
    }

    public int getErrorCode() {
        return errorCode;
    }

    public static ErrorCodes getErrorCodeByNumber(Integer errorNumber) {
        return errorCodeByErrorNumber.get(errorNumber);
    }
}

من أجل عمليات التعداد الأكثر شيوعًا ، تحقق من هذا: كيفية استخدام Enums في java




يمكنك استخدام جدول بحث ثابت:

public enum Suit {
  spades, hearts, diamonds, clubs;

  private static final Map<Integer, Suit> lookup = new HashMap<Integer, Suit>();

  static{
    int ordinal = 0;
    for (Suit suit : EnumSet.allOf(Suit.class)) {
      lookup.put(ordinal, suit);
      ordinal+= 1;
    }
  }

  public Suit fromOrdinal(int ordinal) {
    return lookup.get(ordinal);
  }
}



Related



Tags

java java   enums