8

我想要一个ListArray某种,存储有关每个国家/地区的信息:

  • 2个字母代码
  • 巴西等国名
  • 世界各大洲/地区,如东欧、北美等。

我将手动将每个国家/地区分类为区域/大陆(但如果存在自动执行此操作的方法,请告诉我)。这个问题是关于如何存储和访问国家的。例如,我希望能够检索北美的所有国家/地区。

我不想使用本地文本文件等,因为该项目将使用 Google Web Toolkit 转换为 javascript。但是存储在 Enum 或其他某种资源文件中,将其与其他代码分开,这才是我真正想要的。

4

5 回答 5

14

只需创建一个名为 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 并键入该字段,这将是标准解决方案。由于您对大陆有多个值,因此您必须使用 aMap<?, List<Country>>或 Multimap 实现,例如来自 Apache commons。

于 2009-04-03T12:26:26.087 回答
5

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 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);
    }
}

当然,如果您需要通过 ISO 2 字母代码查找国家/地区,您可能不会将 List 更改为 Map。如您所述,如果您需要按大洲划分国家/地区,您可以从 ISO 3166 扩展 XML 并添加您自己的元素。只需检查他们的(ISO 网站)许可证。

于 2009-04-03T13:34:33.770 回答
4

如果您经常需要按大陆进行查找,我只需制作一系列不可变列表,每个大陆都有一个,并相应地填充它们。一个大陆的国家/地区数据列表可能不会频繁地更改,以支付在需要更改某些内容时重建这样一个要重建的阵列的成本。

此外,如果您愿意手动进行国家/地区分类,其余的都是自动的,可以通过编程方式完成。

于 2009-04-03T12:17:57.230 回答
2

最简单的方法是使用地图(或任何集合)在 Java 中创建国家/大陆结构,然后使用XStream将其持久化

这将创建集合的 XML 表示,您可以非常轻松地将其读入您的流程并将其转换回您最初创建的相同集合类型。此外,由于它是 XML,您可以在代码之外轻松地对其进行编辑。即只是在文本编辑器中。

有关详细信息,请参阅XStream 教程

于 2009-04-03T13:40:40.540 回答
0

using the Locale object is the best solution I can think of, you wouldn't need to store anything. But if you are using GWT try to do that on the server side, as some say you won't get it working correctly on the client side (as it gets translated to javascript) you can send them to the client in an RPC as stated before.

于 2012-01-19T01:24:03.540 回答