在Java中存储国家代码、名称和大陆的最佳方法
我想要一个某种在Java中存储国家代码、名称和大陆的最佳方法,java,arrays,linked-list,hashmap,treemap,Java,Arrays,Linked List,Hashmap,Treemap,我想要一个某种列表或数组,存储每个国家的信息: 2字母代码 国家名称,如巴西 世界大陆/地区,如东欧、北美等 我将手动将每个国家划分为区域/大陆(但如果有自动分类的方法,请告诉我)。这个问题是关于如何存储和访问这些国家。例如,我希望能够检索北美的所有国家 我不想使用本地文本文件,因为这个项目将使用GoogleWebToolkit转换为javascript。但我真正想要的是存储在枚举或其他某种资源文件中,使其与代码的其余部分分开。如果您经常需要按大陆进行查找,我只需为每个大陆创建一系列不可变列
列表
或数组
,存储每个国家的信息:
- 2字母代码
- 国家名称,如巴西
- 世界大陆/地区,如东欧、北美等
我不想使用本地文本文件,因为这个项目将使用GoogleWebToolkit转换为javascript。但我真正想要的是存储在枚举或其他某种资源文件中,使其与代码的其余部分分开。如果您经常需要按大陆进行查找,我只需为每个大陆创建一系列不可变列表,并相应地填充它们。一个大陆的国家数据列表可能不会频繁变化,以至于在需要更改某些内容时,重建这样一个阵列的成本无法重建 此外,如果您愿意手动进行国家/大陆分类,那么其余的分类是自动的,可以通过编程方式完成
- 用于获取国家/地区代码列表
- 用于获取每个国家/地区的显示名称
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;
}
}
至于存储和访问,标准解决方案是为您要搜索的每个字段创建一个映射,并键入该字段。由于该大陆有多个值,您必须使用
地图ISO 3166中有246个国家,您可能会在后面得到一个中继大枚举。我更喜欢将XML文件与国家列表一起使用,您可以从中下载并加载它们(例如,当应用程序启动时)。
然后,当您需要在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 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);
}
}
import java.util.ArrayList;
导入java.util.List;
导入java.io.InputStream;
导入org.dom4j.Attribute;
导入org.dom4j.Document;
导入org.dom4j.DocumentException;
导入org.dom4j.Element;
导入org.dom4j.io.SAXReader;
公共类国家服务
{
私有静态最终字符串EL_COUNTRY=“ISO_3166-1_Entry”;
私有静态最终字符串EL_COUNTRY_NAME=“ISO_3166-1_COUNTRY_NAME”;
私有静态最终字符串EL_COUNTRY_CODE=“ISO_3166-1_Alpha-2_CODE_元素”;
私有列表国家=新的ArrayList();
公共国家服务(输入流国家列表)
{
parseCountriesList(countriesList);
}
国家/地区公共列表()
{
返回国;
}
私有void parseCountriesList(InputStream countriesList)
{
国家。清除();
尝试
{
文档=解析(countriesList);
元素根=document.getRootElement();
//未检查
迭代器i=root.element迭代器(EL_国家);
while(i.hasNext())
{
元素countryElement=i.next();
Element countryName=countryElement.Element(EL_COUNTRY_NAME);
元素countryCode=countryElement.Element(EL_国家代码);
字符串countryname=countryname.getText();
添加(新国家(countryname,countryCode.getText());
}
}
捕获(文档异常)
{
日志错误(e,“无法读取国家列表”);
}
捕获(IOE异常)
{
日志错误(e,“无法读取国家列表”);
}
}
公共静态文档解析(InputStream InputStream)引发DocumentException
{
SAXReader=新SAXReader();
返回reader.read(inputStream);
}
}
当然,若你们需要通过ISO2字母代码查找国家,你们可能不会将列表更改为地图。
如您所述,如果您需要按大陆划分不同的国家,您可以从ISO 3166扩展XML并添加您自己的元素。只需查看他们的(ISO网站)许可证。最简单的方法是使用地图(或任何集合)在Java中创建国家/大陆结构,然后使用
这将创建集合的XML表示,您可以非常轻松地将其读入流程,并将其转换回最初创建的集合类型。此外,由于它是XML,您可以在代码之外轻松地编辑它。i、 只是在文本编辑器中
有关更多信息,请参阅。使用Locale对象是我能想到的最佳解决方案,您不需要存储任何内容。
但是,如果您正在使用GWT,请尝试在服务器端这样做,正如有人说的那样,您将无法在客户端正确运行GWT(因为它被转换为javascript),您可以像前面所说的那样,通过RPC将它们发送到客户端。不可变列表是什么意思?你能分享一些代码吗?对不起,我是Java的新手。不可变列表的内容是不能更改的(请参阅ReadOnlyCollection)。但是,我更喜欢Michael的方法,我认为你应该采用这种方法而不是我的方法。它们可以组合在一起:enum Country{…static{for(大陆c:Continental.values())for(Country cc:Country.values())if(cc.GetContinental()==c)ByContinental.get(c).add