2010-09-07 7 views
5

Je viens de lire un tutoriel sur enums et j'ai une question. J'ai étudié exemple:Java Enums 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(); 
    } 
} 

et question: Comment puis-je trouver le type enum par exemple MERCURY si je sais masse et le rayon? Merci.

+5

PLUTO est pas une planète ... ils disent – irreputable

+0

@irreputable: Plus maintenant ... –

+0

La masse et le rayon sont des clés uniques, vous devriez donc être capable de chercher sur l'un ou l'autre. –

Répondre

13

O (n) - itérer toutes les valeurs enum et comparer:

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

Le meilleur endroit pour mettre c'est comme méthode static dans la classe enum elle-même.

+0

Merci beaucoup, oui cela fonctionne. – jitm

+1

Merci de confirmer la stabilité du langage Java. –

3

Donnez le Planet enum une méthode statique search qui accepte ces deux faits et le recherche. Pour quelque chose de cette taille, une stratégie de sonde linéaire simple devrait être assez rapide.

+0

Plus précisément, une méthode de recherche * statique *. – StriplingWarrior

+1

Bon point; J'avais supposé que c'était compris, mais mieux d'être explicite. –

0

Vous pouvez obtenir un tableau de tous les Planet s en utilisant Planet.values(), et parcourez-les, en recherchant celui qui a la masse et le rayon spécifiés.

2

Pour une enum la méthode values() retournera un tableau contenant toutes les valeurs du enum dans l'ordre où elles sont déclarées. Vous pouvez donc simplement parcourir le tableau en recherchant le Planet qui correspond à vos critères.

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

Un enum est peu probable d'avoir un grand nombre de valeurs si ce sera généralement bonne performance sage.

+7

Vous devriez faire attention en comparant les doubles avec ==. – Darron

2

Les motifs de recherche linéaire décrits sont idéaux pour le problème posé. Cependant, dans la situation où la classe enum augmente (ou si vous utilisez des énumérations sécurisées pré-Java 1.5 en utilisant EnumSyntax pour créer des énumérations configurées au moment de l'exécution), vous voudrez peut-être quelque chose d'un peu plus rapide. Dans ce cas, vous pouvez définir un bloc d'initialisation statique qui remplit une carte avec les valeurs afin que vous puissiez rechercher des paires clé-valeur. Dans ce cas, vous définissez Map> qui est saisi par la masse puis le rayon. Vous devez ensuite fournir une méthode statique qui renvoie la recherche à partir de la carte.

Cette surcharge est dans la plupart des cas puisque la recherche linéaire est plus que suffisante pour la performance. Mais si vous effectuez ces recherches plusieurs fois, alors cette solution fournit un hit unique à l'initialisation.

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

}