Hoonta Hoonta - 5 months ago 25
Java Question

In Java, can I declare a HashMap constant?

I am writing a simple program to convert a number to a word representing that number (13 => "thirteen").

I realize I could get some of the words with a constant String array like this:

private static final String[] tensNames = {"", " ten", " twenty", " thirty", " forty", " fifty", " sixty", " seventy", " eighty", " ninety" };


...and access it with the index, but I wanted to try it with a HashMap like this:

final HashMap<Integer, String> tensNumberConversion = new HashMap<Integer, String>();
tensNumberConversion.put(2, "twenty");
tensNumberConversion.put(3, "thirty");
tensNumberConversion.put(4, "forty");
tensNumberConversion.put(5, "fifty");
tensNumberConversion.put(6, "sixty");
tensNumberConversion.put(7, "seventy");
tensNumberConversion.put(8, "eighty");
tensNumberConversion.put(9, "ninety");


I was instructed by a teacher to make these constants. Can the HashMap be a constant? As a newbie, it wasn't totally clear how the terms "constant" and "static" and "final" are related, and what exactly makes a constant. (static alone? final alone? static final together?).

I tried making it private static final Hashmap but IntelliJ gave me an error (modifier 'private' not allowed here...same for 'static').

However, it does compile from my terminal with no errors. If a HashMap can be a constant, is this the right way to declare one? Thanks!

Answer Source

There are two aspects here:

  • You have a variable that holds a reference to a map. You simply declare that variable to be final; and voilà, you can't change the variable to point to another reference.
  • But that doesn't prevent you from changing the state of the object that reference is pointing. So even when you have a final Map object, you could still call put/remove/... methods on that Map.

So, in order to come to a real "constant" Map, you do go for this:

First you create an ordinary map containing all the desired values.

Then you use Collections.unmodifiableMap() in order to create a map that can't be changed any more.

The one thing to pay attention to: you have to make sure that you are not leaking a reference to the original map object as that immutable map is just a wrapper around that initial map. You could do that in a little helper method for example.

If you are asking: is there a way to write down a map declaration in a special "literal form" (like for arrays) - there isn't. Well, you can change that helper method to take Object ... as parameter; and then you would go through those parameters, one is a number, next one a string, and use that to fill the map. So you could then invoke the method with a single sequence of values. But probably not worth the effort ...