2010-09-07 13 views
5

Acabo de leer un tutorial sobre enumeraciones y tengo una pregunta. he estudiado ejemplo:Enumeración de Java enum

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(); 
    } 
} 

y pregunta: ¿Cómo puedo encontrar tipo de enumeración por ejemplo MERCURIO si sé masa y el radio? Gracias.

+5

Plutón es un planeta no ... dicen – irreputable

+0

@irreputable: Ya no es así ... –

+0

La masa y el radio son claves únicas, por lo que debe ser capaz de buscar en cualquiera de los dos. –

Respuesta

13

O (n) - iterar todos los valores de enumeración y compara:

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

El mejor lugar para poner esto es como un método static en la propia clase de enumeración.

+0

Muchas gracias, sí, funciona. – jitm

+1

Gracias por confirmar la estabilidad del lenguaje Java. –

3

Proporcione Planet enum un método estático search que acepta esos dos hechos y lo busca. Para algo de este tamaño, una estrategia de sonda lineal simple debería ser lo suficientemente rápida.

+0

Específicamente, un método de búsqueda * estático *. – StriplingWarrior

+1

Buen punto; Había asumido que se entendía, pero era mejor ser explícito. –

0

Puede obtener una matriz de todos los Planet s utilizando Planet.values() y recorrerlos en iteración, buscando el que tenga la masa y el radio especificados.

2

Para un enum el método values() devolverá una matriz que contiene todos los valores de enum en el orden en que se declaran. De modo que puede recorrer la matriz buscando el Planet que coincida con sus criterios.

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

Un enum es poco probable que tenga un gran número de valores por lo que este será generalmente bien se refiere a rendimiento.

+7

Debe tener cuidado al comparar dobles con ==. – Darron

2

Los patrones de búsqueda lineal discutidos son ideales para el problema planteado. Sin embargo, en la situación en que crece la clase enum (o si usa enums de seguridad anteriores a Java 1.5 con EnumSyntax para crear enumeraciones configuradas en tiempo de ejecución), es posible que desee algo un poco más rápido. En ese caso, podría definir un bloque de inicialización estático que llene un Mapa con los valores para que pueda buscar por pares clave-valor. En este caso, definiría Mapa> que está codificado por la masa y luego por el radio. Debería proporcionar un método estático que devuelva la búsqueda del mapa.

Esto es overkill es la mayoría de las circunstancias ya que la búsqueda lineal es más que suficiente para el rendimiento. Pero si realiza estas búsquedas varias veces, esta solución proporciona un solo golpe en la inicialización.

Código Ejemplo:

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; 
} 

}