Java alternative of bad looking if-else or switch constructions

Viewed 219

Looking for modern way to realise String translation to replace bad looking if-else or switch constructions:

if ("UK".equals(country)) 
     name = "United Kingdom";
  if ("GE".equals(country))
     name = "Germany";
  if ("FR".equals(country))
     name = "France";
  if ("IT".equals(country))
     name = "Italy";
  [...]

or

switch (country) {
      case "UK": name = "United Kingdom"; break;
      case "GE": name = "Germany" break;
      case "FR": name = "France"; break;
      case "IT": name = "Italy" break;
  [...]
4 Answers

You might want an enum.

public enum Country {
    UK("United Kingdom"),
    GE("Germany"), // sure this isn't DE?
    FR("France");
    // and so on
    private String countryName;
    private Country(String n) { countryName = n; }

    public String getCountryName() { return countryName; }
}

Now you can

Country c = Country.valueOf(countryString); // throws exception when unknown
name = c.getCountryName();

I think the cleanest approach would be inheritance and introduce some simple data structure to your code to represent this kind of information. This will stop your switches from escalating when extending your code. Let's have an abstract base class Country which provides some attributes like 'Name'. The name will never change and is specific to the type. So we define a class UK that inherits from Country. Now you can make use of polymorphism and iterate all countries of type Country and retrieve its name by accessing the (read-only) attribute 'Name' without any switches or type casts. When a new country is added you won't have to touch this kind of statements any more.

List<String> countries = new ArrayList<>();
countries.Add(new UK());
countries.Add(new Italy());

for (Country country : countries) 
{
  String countryName = country.getName();
}

One other possibility is with HashMap:

private final Map<String, String> countries = new HashMap<String, String>() {
  {
     put("UK", "United Kingdom");
     put("GE", "Germany");
     put("FR", "France");
     put("IT", "Italy");
     [...]
  }
};

name = countries.get(county);

You can simply use java.util.Map.
create static countries variable.

private static final String UK = "UK";
private static final String GE = "GE";
private static final String FR = "FR";
private static final String IT = "IT";

private static final Map<String, String> COUNTRIES;
static {
    final Map<String, String> countries = new HashMap<>();
    countries.put(UK, "United Kingdom");
    countries.put(GE, "Germany");
    countries.put(FR, "France");
    countries.put(IT, "Italy");
    COUNTRIES = Collections.unmodifiableMap(countries);
}

then can use "get" property from java.util.Map to get the country name

System.out.println(COUNTRIES.get(UK));
System.out.println(COUNTRIES.get(GE));
System.out.println(COUNTRIES.get(FR));
System.out.println(COUNTRIES.get(IT));
Related