Reputation: 2597
I've just read tutorial about enums and have one question. I've studied example:
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();
}
}
and question: How can I find enum type for example MERCURY if I know mass and radius ? Thanks.
Upvotes: 5
Views: 4382
Reputation: 4439
The linear search patterns discussed are ideal for the posed problem. However, in the situation were the enum class grows (or if you're using pre-Java 1.5 type-safe enums using EnumSyntax to create run-time configured enums) you might want something a little faster. In that case, you could define a static initialization block that populates a Map with the values so you can look up by key-value pairs. In this case you would define Map> which is keyed by the mass then the radius. You would then provide a static method that returns the lookup from the map.
This is overkill is most circumstances since the linear search is more than sufficient for performance. But if you're perform these look-ups multiple times, then this solution provides a one-time hit at initialization.
Example Code:
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;
}
}
Upvotes: 2
Reputation: 72039
Give the Planet
enum a static search
method that accepts those two facts and looks it up. For something this size, a simple linear probe strategy should be plenty fast enough.
Upvotes: 4
Reputation: 597412
O(n) - iterate all enum values and compare:
for (Planet planet : Planet.values()) {
if (..) {..}
}
The best place to put this is as a static
method in the enum class itself.
Upvotes: 13
Reputation: 193814
For an enum
the values()
method will return an array containing all of the values of the enum
in the order they are declared. So you can just loop over the array looking for the Planet
that matches your criteria.
for (Planet p : Planet.values()) {
if (p.mass() == searchMass && p.radius == searchRadius) {
//do something with p
}
}
An enum
is unlikely to have a large number of values so this will usually be fine performance wise.
Upvotes: 2
Reputation: 25511
You can get an array of all the Planet
s using Planet.values()
, and iterate through them, looking for the one that has the specified mass and radius.
Upvotes: 0