2010-09-07 29 views
5

Tôi vừa đọc hướng dẫn về enums và có một câu hỏi. tôi đã nghiên cứu ví dụ:Java Enums tìm 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(); 
    } 
} 

và câu hỏi: Làm thế nào tôi có thể tìm thấy kiểu enum Ví dụ MERCURY nếu tôi biết khối lượng và bán kính? Cảm ơn.

+5

PLUTO không phải là một hành tinh ... họ nói – irreputable

+0

@irreputable: Không nữa ... –

+0

Khối lượng và bán kính là chìa khóa độc đáo, vì vậy bạn nên có thể tìm kiếm trên một trong hai. –

Trả lời

13

O (n) - lặp tất cả các giá trị enum và so sánh:

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

Nơi tốt nhất để đặt này là như một phương pháp static trong lớp enum chính nó.

+0

Cảm ơn rất nhiều, có nó hoạt động. – jitm

+1

Cảm ơn bạn đã xác nhận tính ổn định của ngôn ngữ Java. –

3

Cung cấp cho Planet áp dụng phương thức tĩnh search chấp nhận hai sự kiện đó và tìm kiếm nó. Đối với một cái gì đó kích thước này, một chiến lược thăm dò tuyến tính đơn giản nên được rất nhiều đủ nhanh.

+0

Cụ thể, phương pháp tìm kiếm * tĩnh *. – StriplingWarrior

+1

Điểm tốt; Tôi đã giả định nó đã được hiểu, nhưng tốt hơn để được rõ ràng. –

0

Bạn có thể nhận được một mảng của tất cả các Planet s bằng cách sử dụng Planet.values() và lặp qua chúng, tìm kiếm có khối lượng và bán kính được chỉ định.

2

Đối với phương thức enum phương thức values() sẽ trả về một mảng chứa tất cả các giá trị của enum theo thứ tự chúng được khai báo. Vì vậy, bạn chỉ có thể lặp qua mảng tìm kiếm Planet phù hợp với tiêu chí của bạn.

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

An enum không có số lượng lớn các giá trị vì vậy điều này thường sẽ có hiệu suất tốt.

+7

Bạn nên cẩn thận so sánh gấp đôi với ==. – Darron

2

Các mẫu tìm kiếm tuyến tính được thảo luận là lý tưởng cho vấn đề đặt ra. Tuy nhiên, trong tình huống là lớp enum phát triển (hoặc nếu bạn đang sử dụng các Java enumSyntax trước-Java 1.5 để tạo các enum cấu hình thời gian chạy), bạn có thể muốn một thứ nhanh hơn một chút. Trong trường hợp đó, bạn có thể xác định một khối khởi tạo tĩnh điền một Bản đồ với các giá trị để bạn có thể tra cứu các cặp khóa-giá trị. Trong trường hợp này, bạn sẽ định nghĩa Map> được khóa bởi khối lượng rồi bán kính. Sau đó, bạn sẽ cung cấp phương thức tĩnh trả về tra cứu từ bản đồ.

Đây là trường hợp quá mức cần thiết vì tìm kiếm tuyến tính quá đủ để thực hiện. Nhưng nếu bạn thực hiện các lần tra cứu này nhiều lần, thì giải pháp này cung cấp lần truy cập một lần khi khởi tạo.

Ví dụ 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; 
} 

}