簡體   English   中英

通過數字ID獲取枚舉的最佳方法

[英]Best way to get an enum by numeric id

我需要創建一個包含大約300個值的枚舉,並且能夠通過id(int)獲取其值。 我目前有這個:

public enum Country {
    DE(1), US(2), UK(3);

    private int id;
    private static Map<Integer, Country> idToCountry = new HashMap<>();
    static {
        for (Country c : Country.values()) {
            idToCountry.put(c.id, c);
        }
    }

    Country(int id) {
        this.id = id;
    }

    public static Country getById(int id) {
        return idToCountry.get(id);
    }
}

這個枚舉將會被大量使用,所以我想知道這是否是性能最佳的解決方案。

我一遍又一遍地閱讀http://docs.oracle.com/javase/1.5.0/docs/guide/language/enums.html ,但找不到描述的時間部分

static {

}

調用塊,如果確保它只被調用一次。 那么 - 是嗎?

如果第一個國家/地區ID為0且ID增加1 ,您可以使用下一個方法:

  1. 緩存數組中的枚舉值。 Enum.values()以與枚舉中聲明的順序相同的順序返回元素。 但它應該被緩存,因為它每次調用時都會創建新數組。
  2. 通過id從緩存數組中獲取值,這將是數組索引。

請看下面的代碼:

enum Country {
    A, B, C, D, E;
    private static final Country[] values = Country.values();

    public static Country getById(int id) {
        return values[id];
    }
}

更新:要獲取Country的id,應使用ordinal()方法。 為了使id代碼更清晰,可以將下一個方法添加到枚舉中:

public int getId() {
    return ordinal();
}

初始化類時,會調用一次靜態初始化程序塊。 它不能保證被稱為一次,但除非你正在用類加載器做一些異國情調。

因此,從性能角度來看,您的方法可能很好。 我建議的唯一變化是讓你的領域final


表示映射的另一種方法是將元素存儲在數組(或列表)中:

Country[] countries = new Countries[maxId + 1];
for (Country country : Country.values()) {
  countries[country.id] = country;
}

然后,您可以按元素索引查找它們:

System.out.println(countries[1]);  // DE.

這避免了為了調用idToCountry.get(Integer)必須idToCountry.get(Integer) id的性能損失。

這當然要求您具有非負ID(理想情況下,ID將是合理連續的,以避免必須在國家之間存儲大量null )。

首先,您不需要使用靜態塊來創建地圖。 您只需將代碼添加到構造函數中,其中每個組件都將自己添加到地圖中。 Enum總是一個sigleton所以你的構造函數只能被調用一次(每個枚舉值)你也不需要ID,因為Enum有方法public final int ordinal()返回它的從零開始的順序號。枚舉。 在你的情況下,對於DE,1對於美國和2英國,序數將為0。

這是一個例子:

public enum Country {
DE, US, UK;

private static Map<Integer, Country> idToCountry = new HashMap<>();

    Country() {
       idToCountry.put(this.ordinal(), this);
    }

    public static Country getById(int id) {
        return idToCountry.get(id);
    }
}

你也可以嘗試這個。 很簡單,因為它顯示。

enum Country {
  DE(1), US(2), UK(3);

  public int id;

  Country(int id) {
  this.id = id;
}

 public static Country getCountry(int id) {
    Country[] c = new Country[Country.values().length];
    c = Country.values();
    return c[id];
  }
}

非常感謝。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM