2010-09-07 39 views
5

Ho appena letto il tutorial sull'enumerazione e ho una domanda. Ho studiato esempio:Java Enum find 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(); 
    } 
} 

e domanda: Come posso trovare tipo enum per esempio MERCURY se so di massa e raggio? Grazie.

+5

PLUTO non è un pianeta ... dicono – irreputable

+0

@irreputable: Ora non più ... –

+0

La massa e il raggio sono chiavi univoche, così si dovrebbe essere in grado di cercare su entrambi. –

risposta

13

O (n) - iterare tutti i valori enum e confrontare:

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

Il posto migliore per mettere questo è come un metodo static nella classe enum stesso.

+0

Grazie mille, sì funziona. – jitm

+1

Grazie per aver confermato la stabilità del linguaggio Java. –

3

Dare il Planet enum un metodo statico search che accetta quei due fatti e lo cerca. Per qualcosa di queste dimensioni, una semplice strategia di sonda lineare dovrebbe essere abbastanza veloce.

+0

In particolare, un metodo di ricerca * statico *. – StriplingWarrior

+1

Buon punto; Avevo pensato che fosse capito, ma meglio essere espliciti. –

0

È possibile ottenere un array di tutti gli Planet s utilizzando Planet.values() e scorrere attraverso di essi, cercando quello con la massa e il raggio specificati.

2

Per un enum il metodo values() restituirà un array contenente tutti i valori di enum nell'ordine in cui sono dichiarati. Quindi puoi semplicemente eseguire il loop sull'array cercando il Planet corrispondente ai tuoi criteri.

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

Un enum è improbabile che abbia un gran numero di valori per cui questo di solito è bella prestazione saggia.

+7

Dovresti fare attenzione a confrontare i doppi con ==. – Darron

2

I modelli di ricerca lineare discussi sono ideali per il problema posto. Tuttavia, nella situazione in cui la classe enum cresce (o se si utilizzano enum sicuri pre-Java 1.5 utilizzando EnumSyntax per creare enum configurati in fase di esecuzione) si potrebbe desiderare qualcosa di un po 'più veloce. In tal caso, è possibile definire un blocco di inizializzazione statico che compila una mappa con i valori in modo da poter cercare le coppie chiave-valore. In questo caso dovresti definire Mappa> che è digitato dalla massa e dal raggio. Fornirai quindi un metodo statico che restituisce la ricerca dalla mappa.

Questa è la maggior parte delle circostanze poiché la ricerca lineare è più che sufficiente per le prestazioni. Ma se si eseguono queste ricerche più volte, questa soluzione fornisce un colpo unico all'inizializzazione.

Esempio di codice:

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

}