2010-09-07 312 views
5

我剛剛閱讀關於枚舉的教程,並有一個問題。 我研究例如:Java枚舉找到枚舉

public enum Planet { 
    MERCURY (3.303e+23, 2.4397e6), 
    VENUS (4.869e+24, 6.0518e6), 
    EARTH (5.976e+24, 6.37814e6), 
    MARS (6.421e+23, 3.3972e6), 
    JUPITER (1.9e+27, 7.1492e7), 
    SATURN (5.688e+26, 6.0268e7), 
    URANUS (8.686e+25, 2.5559e7), 
    NEPTUNE (1.024e+26, 2.4746e7), 
    PLUTO (1.27e+22, 1.137e6); 

    private final double mass; // in kilograms 
    private final double radius; // in meters 
    Planet(double mass, double radius) { 
     this.mass = mass; 
     this.radius = radius; 
    } 
    public double mass() { return mass; } 
    public double radius() { return radius; } 

    // universal gravitational constant (m3 kg-1 s-2) 
    public static final double G = 6.67300E-11; 

    public double surfaceGravity() { 
     return G * mass/(radius * radius); 
    } 
    public double surfaceWeight(double otherMass) { 
     return otherMass * surfaceGravity(); 
    } 
} 

和問題:我如何才能找到例如MERCURY枚舉類型,如果我知道的質量和半徑? 謝謝。

+5

冥王星是不是行星......他們說 – irreputable 2010-09-07 18:29:01

+0

@irreputable:現在不一樣了... – 2010-09-07 18:44:13

+0

的質量和半徑是唯一的鑰匙,所以你應該能夠搜索任何一個。 – 2010-09-07 19:18:28

回答

13

爲O(n) - 遍歷所有枚舉值和比較:

for (Planet planet : Planet.values()) { 
    if (..) {..} 
} 

最好的地方,把這個作爲在枚舉類本身就是一個static方法。

+0

非常感謝,是的它的工作原理。 – jitm 2010-09-07 18:26:26

+1

謝謝您確認Java語言的穩定性。 – 2010-09-07 18:27:11

3

Planet枚舉一個靜態的search方法,接受這兩個事實並查找它。對於這樣大小的東西,一個簡單的線性探測策略應該足夠快。

+0

具體而言,一個*靜態*搜索方法。 – StriplingWarrior 2010-09-07 18:24:28

+1

好點;我認爲這是理解的,但更好的是明確的。 – 2010-09-07 19:21:52

0

您可以使用Planet.values()獲得所有Planet的數組,並遍歷它們,查找具有指定質量和半徑的數組。

2

對於enumvalues()方法將返回一個包含enum所有值的數組,它們按聲明的順序排列。因此,您只需循環查找符合您標準的Planet即可。

for (Planet p : Planet.values()) { 
    if (p.mass() == searchMass && p.radius == searchRadius) { 
     //do something with p 
    } 
} 

enum不太可能有大量的值所以這通常是優良性能明智的。

+7

你應該小心比較雙打==。 – Darron 2010-09-07 18:40:39

2

討論的線性搜索模式對於所提出的問題是理想的。但是,在enum類增長的情況下(或者如果您使用EnumSyntax創建運行時配置的枚舉時使用Java 1.5之前的類型安全枚舉),您可能需要更快一點的東西。 在這種情況下,您可以定義一個靜態初始化塊,使用這些值填充Map,以便您可以按鍵值對查找。在這種情況下,您可以定義Map>,然後通過質量鍵入半徑。 然後,您將提供一個靜態方法,該方法返回來自地圖的查找。

由於線性搜索對於性能來說已經綽綽有餘,這是多數情況下的矯枉過正。但是如果你多次執行這些查找,那麼這個解決方案會在初始化時提供一次性命中。

示例代碼:

public enum Planet { 
MERCURY (3.303e+23, 2.4397e6), 
VENUS (4.869e+24, 6.0518e6), 
EARTH (5.976e+24, 6.37814e6), 
MARS (6.421e+23, 3.3972e6), 
JUPITER (1.9e+27, 7.1492e7), 
SATURN (5.688e+26, 6.0268e7), 
URANUS (8.686e+25, 2.5559e7), 
NEPTUNE (1.024e+26, 2.4746e7), 
PLUTO (1.27e+22, 1.137e6); 

static { 
    map = new HashMap<Double, Map<Double, Planet>>(); 
    for (Planet p : Planet.values()) { 
     if (!map.containsKey(p.getMass())) { 
     p.put(p.getMass(), new HashMap<Double, Planet>()); 
     } 
     p.get(p.getMass()).put(p.getRadius(), p)); 
    } 
} 

private final double mass; // in kilograms 
private final double radius; // in meters 

private static final Map<Double, Map<Double, Planet>> map; 

Planet(double mass, double radius) { 
    this.mass = mass; 
    this.radius = radius; 
} 
public double mass() { return mass; } 
public double radius() { return radius; } 

// universal gravitational constant (m3 kg-1 s-2) 
public static final double G = 6.67300E-11; 

public double surfaceGravity() { 
    return G * mass/(radius * radius); 
} 
public double surfaceWeight(double otherMass) { 
    return otherMass * surfaceGravity(); 
} 

public static Planet getPlanet(double mass, double radius) { 
    if (map.contains(mass)) { 
     return map.get(mass).get(radius); 
    } 
    return null; 
} 

}