Currently I'm using a HashMap to map the strings to int and the int values need to be frequently accessed. I'm looking for a better way to do this if possible with minimal object creation, and preferable being able to store the values as primitive ints without wrapping them with the Integer class. (Basically, the reverse of the SparseArray's int->object mapping.)
If you're using a HashMap there will be no way around using some object. If you're max value is 31 all values will be cached by the Integer implementation. There will be no object createion as long as you're using autoboxing or Integer.valueOf to access the Integer instances (not new Integer(..)
).
If you want to minimize object creation you could write an mutable wrapper around a primitive int. One alternative is to (mis-)use java.util.concurrent.atomic.AtomicInteger which has some overhead.
Use String[32]
. The index is your int
value. Hold null
for any slot in the array where you have no corresponding String
.
EDIT: Sorry, this is for an int->String
lookup. For String
->int, you can still use String[32]
, but you'd need to store them in sorted order and use Arrays#binarySearch()
or something. I really think you should just stick with the HashMap
.
Write a class like this:
public class Foo
{
public static final String A = "a";
public static final String B = "b";
public static int foo(String str)
{
final int val;
if(str == A || str.equals(A))
{
val = 0x01;
}
else if(str == B || str.equals(B))
{
val = 0x02;
}
// etc...
return (val);
}
}
You only create the Strings once each, the number of Strings are small enough that the .equals won't get called many times, and if you always us ethe constants then the .equals won't get called at all.
If you use a Map it will take more memory than this, and also given that the number of Strings is small the code above might be faster. Also you can refactor the implementation to use a Map internally (or an array, or whatever) and see what is the fastest/uses the least memory without having to change your API.
EDIT:
Another thing to look at is the proposal for switch with String... if this comes into the language (I think it is) and if Android adopts it, then you would be able to replace the code I have above with a switch without a performance hit. Essentially they do a switch on the hashCode and then only call .equals on objects that have the same hashCode. This does require that you figure out the hashCodes in advance, and that the hashCode always returns the same thing for ever (which it should since String defines the way hashCode must work).