DocRobson
DocRobson

Reputation: 125

Alternative ways for hard-coding Map in Java?

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?

Upvotes: 8

Views: 12927

Answers (4)

Aaron
Aaron

Reputation: 24812

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.


Edited in 2024 :

The above is only acceptable for Java 8 and earlier.
In Java 9+ you will want to use the Map.of(...) methods :

Map<Integer,String> myMap = Map.of(
    1, "String1",
    2, "String2"
)

Note that the resulting Map is immutable ; if that's not good for you you can build a mutable Map from it :

Map<Integer, String> myMap = new HashMap<>(Map.of(...));

Upvotes: 4

Ranjit
Ranjit

Reputation: 144

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) : "";

   }
 }

Upvotes: 0

OldCurmudgeon
OldCurmudgeon

Reputation: 65859

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.

Upvotes: 0

Suresh Atta
Suresh Atta

Reputation: 122006

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.

Upvotes: 7

Related Questions