Is there an open source java enum of ISO 3166-1 country codes

JavaInternationalizationCountry CodesIso 3166

Java Problem Overview


Does anyone know of a freely available java 1.5 package that provides a list of ISO 3166-1 country codes as a enum or EnumMap? Specifically I need the "ISO 3166-1-alpha-2 code elements", i.e. the 2 character country code like "us", "uk", "de", etc. Creating one is simple enough (although tedious), but if there's a standard one already out there in apache land or the like it would save a little time.

Java Solutions


Solution 1 - Java

Now an implementation of country code (ISO 3166-1 alpha-2/alpha-3/numeric) list as Java enum is available at GitHub under Apache License version 2.0.

Example:

CountryCode cc = CountryCode.getByCode("JP");

System.out.println("Country name = " + cc.getName());                // "Japan"
System.out.println("ISO 3166-1 alpha-2 code = " + cc.getAlpha2());   // "JP"
System.out.println("ISO 3166-1 alpha-3 code = " + cc.getAlpha3());   // "JPN"
System.out.println("ISO 3166-1 numeric code = " + cc.getNumeric());  // 392

Last Edit 2016-Jun-09

CountryCode enum was packaged into com.neovisionaries.i18n with other Java enums, LanguageCode (ISO 639-1), LanguageAlpha3Code (ISO 639-2), LocaleCode, ScriptCode (ISO 15924) and CurrencyCode (ISO 4217) and registered into the Maven Central Repository.

Maven

<dependency>
  <groupId>com.neovisionaries</groupId>
  <artifactId>nv-i18n</artifactId>
  <version>1.29</version>
</dependency>

Gradle

dependencies {
  compile 'com.neovisionaries:nv-i18n:1.29'
}

GitHub

https://github.com/TakahikoKawasaki/nv-i18n

Javadoc

https://takahikokawasaki.github.io/nv-i18n/

OSGi

Bundle-SymbolicName: com.neovisionaries.i18n
Export-Package: com.neovisionaries.i18n;version="1.28.0"

Solution 2 - Java

This code gets 242 countries in Sun Java 6:

String[] countryCodes = Locale.getISOCountries();

Though the ISO website claims there are 249 ISO 3166-1-alpha-2 code elements, though the javadoc links to the same information.

Solution 3 - Java

Here's how I generated an enum with country code + country name:

package countryenum;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Locale;

public class CountryEnumGenerator {
    public static void main(String[] args) {
        String[] countryCodes = Locale.getISOCountries();
        List<Country> list = new ArrayList<Country>(countryCodes.length);

        for (String cc : countryCodes) {
            list.add(new Country(cc.toUpperCase(), new Locale("", cc).getDisplayCountry()));
        }

        Collections.sort(list);

        for (Country c : list) {
            System.out.println("/**" + c.getName() + "*/");
            System.out.println(c.getCode() + "(\"" + c.getName() + "\"),");
        }

    }
}

class Country implements Comparable<Country> {
    private String code;
    private String name;

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

    public String getCode() {
        return code;
    }


    public void setCode(String code) {
        this.code = code;
    }


    public String getName() {
        return name;
    }


    public void setName(String name) {
        this.name = name;
    }


    @Override
    public int compareTo(Country o) {
        return this.name.compareTo(o.name);
    }
}

Solution 4 - Java

If you are already going to rely on Java locale, then I suggest using a simple HashMap instead of creating new classes for countries etc.

Here's how I would use it if I were to rely on the Java Localization only:

private HashMap<String, String> countries = new HashMap<String, String>();
String[] countryCodes = Locale.getISOCountries();

for (String cc : countryCodes) {
    // country name , country code map
    countries.put(new Locale("", cc).getDisplayCountry(), cc.toUpperCase());
}

After you fill the map, you can get the ISO code from the country name whenever you need it. Or you can make it a ISO code to Country name map as well, just modify the 'put' method accordingly.

Solution 5 - Java

There is an easy way to generate this enum with the language name. Execute this code to generate the list of enum fields to paste :

 /**
  * This is the code used to generate the enum content
  */
 public static void main(String[] args) {
  String[] codes = java.util.Locale.getISOLanguages();
  for (String isoCode: codes) {
   Locale locale = new Locale(isoCode);
   System.out.println(isoCode.toUpperCase() + "(\"" + locale.getDisplayLanguage(locale) + "\"),");
  }
 }

Solution 6 - Java

If anyone is already using the Amazon AWS SDK it includes com.amazonaws.services.route53domains.model.CountryCode. I know this is not ideal but it's an alternative if you already use the AWS SDK. For most cases I would use Takahiko's nv-i18n since, as he mentions, it implements ISO 3166-1.

Solution 7 - Java

Not a java enum, but a JSON version of this is available at http://country.io/names.json

Solution 8 - Java

AWS Java SDK has CountryCode.

Solution 9 - Java

This still does not answer the question. I was also looking for a kind of enumerator for this, and did not find anything. Some examples using hashtable here, but represent the same as the built-in get

I would go for a different approach. So I created a script in python to automatically generate the list in Java:

#!/usr/bin/python
f = open("data.txt", 'r')
data = []
cc = {}

for l in f:
    t = l.split('\t')
    cc = { 'code': str(t[0]).strip(), 
           'name': str(t[1]).strip()
    }
    data.append(cc)
f.close()

for c in data:
    print """
/**
 * Defines the <a href="http://en.wikipedia.org/wiki/ISO_3166-1_alpha-2">ISO_3166-1_alpha-2</a> 
 * for <b><i>%(name)s</i></b>.
 * <p>
 * This constant holds the value of <b>{@value}</b>.
 *
 * @since 1.0
 *
 */
 public static final String %(code)s = \"%(code)s\";""" % c

where the data.txt file is a simple copy&paste from Wikipedia table (just remove all extra lines, making sure you have a country code and country name per line).

Then just place this into your static class:

/**
 * Holds <a href="http://en.wikipedia.org/wiki/ISO_3166-1_alpha-2">ISO_3166-1_alpha-2</a>
 * constant values for all countries. 
 * 
 * @since 1.0
 * 
 * </p>
 */
public class CountryCode {

    /**
     * Constructor defined as <code>private</code> purposefully to ensure this 
     * class is only used to access its static properties and/or methods.  
     */
    private CountryCode() { }

    /**
     * Defines the <a href="http://en.wikipedia.org/wiki/ISO_3166-1_alpha-2">ISO_3166-1_alpha-2</a> 
     * for <b><i>Andorra</i></b>.
     * <p>
     * This constant holds the value of <b>{@value}</b>.
     *
     * @since 1.0
     *
     */
     public static final String AD = "AD";

         //
         // and the list goes on! ...
         //
}
    

Solution 10 - Java

I didn't know about this question till I had just recently open-sourced my Java enum for exactly this purpose! Amazing coincidence!

I put the whole source code on my blog with BSD caluse 3 license so I don't think anyone would have any beefs about it.

Can be found here. https://subversivebytes.wordpress.com/2013/10/07/java-iso-3166-java-enum/

Hope it is useful and eases development pains.

Solution 11 - Java

I have created an enum, which you address by the english country name. See country-util.
On each enum you can call getLocale() to get the Java Locale.

From the Locale you can get all the information you are used to, fx the ISO-3166-1 two letter country code.

public enum Country{

    ANDORRA(new Locale("AD")),
    AFGHANISTAN(new Locale("AF")),
    ANTIGUA_AND_BARBUDA(new Locale("AG")),
    ANGUILLA(new Locale("AI")),
    //etc
    ZAMBIA(new Locale("ZM")),
    ZIMBABWE(new Locale("ZW"));

    private Locale locale;

    private Country(Locale locale){
    	this.locale = locale;
    }

    public Locale getLocale(){
    	return locale;
    }

Pro:

  • Light weight
  • Maps to Java Locales
  • Addressable by full country name
  • Enum values are not hardcoded, but generated by a call to Locale.getISOCountries(). That is: Simply recompile the project against the newest java version to get any changes made to the list of countries reflected in the enum.

Con:

  • Not in Maven repository
  • Most likely simpler / less expressive than the other solutions, which I don't know.
  • Created for my own needs / not as such maintained. - You should probably clone the repo.

Solution 12 - Java

There is standard java.util.Locale.IsoCountryCode since Java 9.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionJason JenkinsView Question on Stackoverflow
Solution 1 - JavaTakahiko KawasakiView Answer on Stackoverflow
Solution 2 - JavaMcDowellView Answer on Stackoverflow
Solution 3 - JavaBozhoView Answer on Stackoverflow
Solution 4 - JavasskularView Answer on Stackoverflow
Solution 5 - JavaChristophe DesguezView Answer on Stackoverflow
Solution 6 - JavaabdielouView Answer on Stackoverflow
Solution 7 - JavaBen DowlingView Answer on Stackoverflow
Solution 8 - JavaNoel YapView Answer on Stackoverflow
Solution 9 - Javabruno.bragaView Answer on Stackoverflow
Solution 10 - Javageorge_hView Answer on Stackoverflow
Solution 11 - JavaHervianView Answer on Stackoverflow
Solution 12 - JavaVadzimView Answer on Stackoverflow