Alternative ways for hard-coding Map in Java?

Viewed 8131

I'm having a HashMap in my Java program consisting of around 200 -Key-Value-pairs which won't change during runtime and I am looking for a good way to initialize all the pairs. Currently I have a hard-coded method like this

private void initializeHashMap(){
    hashMap.put(1, "String1");
    hashMap.put(2, "String2");
    hashMap.put(3, "String3");
...}

for all the 200 pairs. Is that really good practice or is there another, better way maybe to read the data from another class or an external file?

4 Answers

This is the perfect use case to consider a properties file. When you read the file, it gives you a handy map to play with it.

An alternative which is worse in terms of readability but better in terms of concision (that I'll employ in personal projects but avoid in team work) would be to use an anonymous class that defines its key/values at instanciation :

Map<Integer,String> myMap = new HashMap<Integer,String>(){{
    this.put(1, "String1");
    this.put(2, "String2");
}};

Now you're not instantiating an HashMap anymore but an anonymous class that extends it. This anonymous class' definition contains an instance initializer block that will be executed after the constructor and will set up the desired key/values.

I find using streaming of a hard-coded array can be a quite neat method.

String[] contents = new String[] {
        "1:String1",
        "2:String2",
        "3:String3"
};
Map<Integer,String> hashMap = Arrays.stream(contents)
        .collect(Collectors.toMap(
                // Key.
                s -> Integer.valueOf(s.split(":")[0]),
                // Value.
                s -> s.split(":")[1]
        ));

The data list is much easier to maintain and you can often keep it up-to-date from a spreadsheet for example.

You can consider properties file as it will return you map and it helps for configuration and testing.

If you are interested to maintain a separate class for the same then you can go ahead with the instance block,

   public Class Data{
      private static class MyMap extends HashMap<Integer, String>{
          private static final long serialVersionUID=1l;
          private MyMap(){
                this.put(1,"string1");
                this.put(2,"string2");
                this.put(3,"string3");
                this.put(4,"string4");
         }
      }
  public static final Map<Integer, String> fixedData=Collections.unmodifiable(new MyMap());
}

Then in your class you can use this as below.

Class YourClass{
     private static final Map<Integer, String> map;
      static{
        map=Data.fixedData;
      }

   public final String getValue(final int key){
      return map.containsKey(key) ? map.get(key) : "";

   }
 }
Related