我刚刚阅读了关于枚举的教程,并提出了一个问题。我研究了一些例子:
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的枚举类型?谢谢。
O(n) - 迭代所有枚举值并进行比较:
for (Planet planet : Planet.values()) {
if (..) {..}
}
放置它的最佳位置是枚举类本身的static
方法。
给Planet
枚举一个静态的search
方法,接受这两个事实并查找它。对于这种尺寸的东西,简单的线性探针策略应该足够快。
对于enum
,values()
方法将返回一个数组,其中包含enum
的所有值,按照它们的声明顺序。所以你可以循环遍历数组,寻找符合你标准的Planet
。
for (Planet p : Planet.values()) {
if (p.mass() == searchMass && p.radius == searchRadius) {
//do something with p
}
}
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;
}
}
您可以使用Planet
获取所有Planet.values()
s的数组,并迭代它们,寻找具有指定质量和半径的数组。