我希望有一种List
或Array
那种,存储有关每个国家的信息:
2个字母代码
国家名称,如巴西
世界大陆/地区,如东欧,北美等.
我会手动将每个国家分类到地区/大陆(但如果有办法自动执行此操作,请告诉我).这个问题是关于如何存储和访问这些国家.例如,我希望能够检索北美的所有国家/地区.
我不想使用本地文本文件等,因为这个项目将使用Google Web Toolkit转换为javascript.但是存储在Enum或其他某种资源文件中,与其他代码分开,就是我真正想要的.
只需制作一个名为Country的枚举.Java枚举可以有属性,因此有您的国家/地区代码和名称.对于非洲大陆,你可能想要另一个枚举.
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; } }
至于存储和访问,您将要搜索的每个字段的一个Map(键入该字段)将是标准解决方案.由于您拥有该大陆的多个值,因此您必须使用a Map, List
或Multimap实现,例如来自Apache commons.
在ISO 3166中有246个国家,你可能会在此背后得到一个继电器大枚举.我更喜欢使用包含国家/地区列表的XML文件,您可以从http://www.iso.org/下载并加载它们(例如,当应用程序启动时).比如,你需要它们在GWT中作为RPC调用加载它们,但记得缓存那些(某种延迟加载),所以你不会每次都加载它们.我认为这无论如何比在代码中保存更好,因为每次访问模块时你都会完成加载完整列表,即使用户不需要使用这个列表.
所以你需要一些能保住国家的东西:
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(); } }
对于GWT,此类需要实现IsSerializable.您可以使用以下命令在服务器端加载:
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 Listcountries = new ArrayList (); public CountriesService(InputStream countriesList) { parseCountriesList(countriesList); } public List getCountries() { return countries; } private void parseCountriesList(InputStream countriesList) { countries.clear(); try { Document document = parse(countriesList); Element root = document.getRootElement(); //noinspection unchecked Iterator 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); } }
当然,如果您需要通过ISO 2字母代码查找国家/地区,您可能不会将List更改为Map.如果您按照提到的那样,按大陆需要单独的国家/地区,则可以从ISO 3166扩展XML并添加自己的元素.只需检查他们的(ISO网站)许可证.