2010-09-07 156 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; 
} 

}