2009-04-03 11 views
7

Tôi muốn có một List hoặc Array của một số loại, lưu trữ thông tin này về mỗi quốc gia:Cách tốt nhất để lưu trữ mã quốc gia, tên, và Continent trong Java

  • 2 chữ mã
  • tên
  • Nước như vậy như Brazil
  • Continent/khu vực của thế giới như Đông Âu, Bắc Mỹ, vv

tôi sẽ phân loại từng nước vào khu vực/lục bằng tay (nhưng nếu có một cách để làm điều này tự động, hãy cho tôi biết). Câu hỏi này là về cách lưu trữ và truy cập các quốc gia. Ví dụ, tôi muốn có thể lấy tất cả các quốc gia ở Bắc Mỹ.

Tôi không muốn sử dụng tệp văn bản cục bộ hoặc như vậy vì dự án này sẽ được chuyển đổi sang javascript bằng Bộ công cụ web của Google. Nhưng lưu trữ trong một Enum hoặc một tập tin tài nguyên của một số loại, giữ nó tách biệt với phần còn lại của mã, là những gì tôi thực sự sau.

+1

Một số quốc gia thuộc hai châu lục (ở châu Âu Thổ Nhĩ Kỳ, Nga và Kazakhstan), mối quan hệ M: N – mjn

+0

đó là vấn đề của họ :). không ai sẽ muốn sử dụng 3 quốc gia cụ thể đó, và nếu họ làm họ có thể tra cứu chúng theo thứ tự bảng chữ cái thay vì theo vùng –

+0

để bạn biết nước nào sẽ không được 'sử dụng'? bạn phải là chuyên gia thực sự ... – mjn

Trả lời

5

Có 246 quốc gia trong ISO 3166, bạn có thể nhận được một enum lớn chuyển tiếp ở mặt sau của điều này. Tôi thích sử dụng tệp XML với danh sách các quốc gia, bạn có thể tải xuống tệp từ http://www.iso.org/ và tải chúng (ví dụ: khi ứng dụng bắt đầu). Hơn nữa, khi bạn cần chúng trong GWT, hãy tải chúng trở lại như cuộc gọi RPC, nhưng hãy nhớ lưu vào bộ nhớ cache (một số loại tải chậm) để bạn không hoàn thành việc tải chúng mỗi lần. Tôi nghĩ rằng điều này sẽ tốt hơn là giữ chúng trong mã, vì bạn sẽ kết thúc với tải danh sách đầy đủ mỗi khi module được truy cập, ngay cả khi người dùng sẽ không cần phải sử dụng danh sách này.

Vì vậy, bạn cần một cái gì đó mà sẽ giữ nước:

public class Country 
{ 
    private final String name; 
    private final String code; 

    public Country(String name, String code) 
    { 
     this.name = name; 
     this.code = code; 
    } 

    public String getName() 
    { 
     return name; 
    } 

    public String getCode() 
    { 
     return code; 
    } 

    public boolean equals(Object obj) 
    { 
     if (this == obj) 
     { 
      return true; 
     } 
     if (obj == null || getClass() != obj.getClass()) 
     { 
      return false; 
     } 

     Country country = (Country) obj; 

     return code.equals(country.code); 
    } 

    public int hashCode() 
    { 
     return code.hashCode(); 
    } 
} 

Đối với GWT lớp này sẽ cần phải thực hiện IsSerializable. Và bạn có thể tải những, về phía máy chủ sử dụng:

import java.util.ArrayList; 
import java.util.List; 
import java.io.InputStream; 

import org.dom4j.Attribute; 
import org.dom4j.Document; 
import org.dom4j.DocumentException; 
import org.dom4j.Element; 
import org.dom4j.io.SAXReader; 

public class CountriesService 
{ 
    private static final String EL_COUNTRY = "ISO_3166-1_Entry"; 
    private static final String EL_COUNTRY_NAME = "ISO_3166-1_Country_name"; 
    private static final String EL_COUNTRY_CODE = "ISO_3166-1_Alpha-2_Code_element"; 
    private List<Country> countries = new ArrayList<Country>(); 

    public CountriesService(InputStream countriesList) 
    { 
     parseCountriesList(countriesList); 
    } 

    public List<Country> getCountries() 
    { 
     return countries; 
    } 

    private void parseCountriesList(InputStream countriesList) 
    { 
     countries.clear(); 
     try 
     { 
      Document document = parse(countriesList); 
      Element root = document.getRootElement(); 
      //noinspection unchecked 
      Iterator<Element> i = root.elementIterator(EL_COUNTRY); 
      while (i.hasNext()) 
      { 
       Element countryElement = i.next(); 
       Element countryName = countryElement.element(EL_COUNTRY_NAME); 
       Element countryCode = countryElement.element(EL_COUNTRY_CODE); 

       String countryname = countryName.getText(); 
       countries.add(new Country(countryname, countryCode.getText())); 
      } 
     } 
     catch (DocumentException e) 
     { 
      log.error(e, "Cannot read countries list"); 
     } 
     catch (IOException e) 
     { 
      log.error(e, "Cannot read countries list"); 
     } 
    } 

    public static Document parse(InputStream inputStream) throws DocumentException 
    { 
     SAXReader reader = new SAXReader(); 
     return reader.read(inputStream); 
    } 
} 

Tất nhiên, nếu bạn cần phải tìm nước bằng ISO 2 mã thư bạn có thể wont thay đổi Danh sách vào Map lẽ. Nếu, như bạn đã đề cập, bạn cần các quốc gia riêng biệt theo lục địa, bạn có thể mở rộng XML từ ISO 3166 và thêm các phần tử của riêng bạn. Chỉ cần kiểm tra giấy phép (trang web ISO) của họ.

4

Nếu bạn thường xuyên cần tra cứu theo lục địa, tôi chỉ cần tạo một chuỗi danh sách bất biến, một danh sách cho mỗi lục địa và điền chúng tương ứng. Danh sách các quốc gia-dữ liệu cho một lục địa có lẽ sẽ không thay đổi thường xuyên đủ cho chi phí xây dựng lại một mảng như vậy để được xây dựng lại khi một cái gì đó cần phải được thay đổi.

Ngoài ra, nếu bạn sẵn sàng thực hiện phân loại theo quốc gia lục địa, phần còn lại là tự động và có thể được thực hiện theo chương trình.

+0

Bạn có ý nghĩa gì với danh sách bất biến? Bạn có thể chia sẻ một số mã không? Xin lỗi, tôi là người mới đến java –

+0

Danh sách bất biến chỉ là một danh sách có nội dung không thể thay đổi được (xem ReadOnlyCollection). Tuy nhiên, tôi thích cách tiếp cận của Michael tốt hơn, và tôi nghĩ bạn nên lấy nó thay vì của tôi. –

+0

Vâng, chúng có thể được kết hợp: enum Quốc gia {... static {for (Continent c: Continent.values ​​()) cho (Quốc gia cc: Country.values ​​()) nếu (cc.getContinent() == c) byContinent.get (c) .add (cc)}/* được chuyển đổi với Collections.immutableList() và immutableMap() */...} – Hugo

13

Chỉ cần tạo một enum gọi là Quốc gia. Java enums có thể có các thuộc tính, do đó, có mã quốc gia và tên của bạn. Đối với lục địa, bạn có thể muốn một enum khác.

public enum Continent 
{ 
    AFRICA, ANTARCTICA, ASIA, AUSTRALIA, EUROPE, NORTH_AMERICA, SOUTH_AMERICA 
} 

public enum Country 
{ 
    ALBANIA("AL", "Albania", Continent.EUROPE), 
    ANDORRA("AN", "Andorra", Continent.EUROPE), 
    ... 

    private String code; 
    private String name; 
    private Continent continent; 

    // get methods go here  

    private Country(String code, String name, Continent continent) 
    { 
     this.code = code; 
     this.name = name; 
     this.continent = continent; 
    } 
} 

Để lưu trữ và truy cập, một Bản đồ cho từng trường bạn sẽ tìm kiếm, được khóa trên trường đó, sẽ là giải pháp chuẩn. Vì bạn có nhiều giá trị cho lục địa, bạn sẽ phải sử dụng số Map<?, List<Country>> hoặc triển khai Multimap, ví dụ: từ Apache commons.

+0

một số ví dụ mã? –

+0

Châu Phi - lục địa bị mất? – mjn

+0

Bạn nên rõ ràng rằng bạn đang lưu trữ phiên bản "en-US" của "tên";) – Hugo

2

Cách dễ nhất để làm điều này là để tạo ra các cấu trúc quốc gia/lục trong Java sử dụng một bản đồ (hoặc bất kỳ bộ sưu tập) và sau đó kiên trì nó bằng cách sử XStream

này sẽ tạo ra một đại diện XML của bộ sưu tập, và bạn có thể đọc nhiều hơn vào quá trình của bạn rất dễ dàng và chuyển đổi nó trở lại cùng một loại bộ sưu tập mà bạn đã tạo ban đầu. Hơn nữa, bởi vì nó là XML, bạn có thể dễ dàng chỉnh sửa nó bên ngoài mã. tức là chỉ trong một trình soạn thảo văn bản.

Xem XStream tutorial để biết thêm thông tin.

0

sử dụng đối tượng Locale là giải pháp tốt nhất mà tôi có thể nghĩ đến, bạn sẽ không cần lưu trữ bất kỳ thứ gì. Nhưng nếu bạn đang sử dụng GWT cố gắng làm điều đó ở phía máy chủ, như một số người nói bạn sẽ không làm cho nó hoạt động chính xác ở phía máy khách (vì nó được dịch sang javascript), bạn có thể gửi chúng cho khách hàng trong RPC đã nêu trước đây.