I. Overview
Enummap is a special kind of map, the special thing is that key needs to be enumerated type, because the enumeration type is characterized by the number of values is fixed, so, for Enummap, it can store the number is fixed. This type of map is relatively straightforward.
Second, the main implementation of the introduction
1. Initialization
Because of the Enummap enum characteristics, it determines the capacity of its container is constant, so, when creating a enummap, we need to specify its size, currently create a enummap mainly in the following ways:
Public Enummap (class<k> keyType): According to the Class type of the key, all possible values of the enumeration are obtained by reflection, resulting in a key array and an array of values.
Public Enummap (enummap<k,? extends v> m): Initializing from another enummap, essentially generating a copy.
Public Enummap (map<k,? extends v> m): Based on another map initialization, compared to the second method, more than a map conversion process
After the three initialization methods, a key array and a value array are created internally, and their sizes are the same. In particular, because the key is fixed for the same class of enum, the key array can be reused.
2. Storage
Let's take a look at the implementation of the put operation
Public v put (K key, V value) { Typecheck (key); // type check int index = key.ordinal (); = Vals[index]; = Masknull (value); // null value handling if NULL ) size++ ; return Unmasknull (OldValue); }
You can see that the entire implementation is very simple, and the value corresponding to the key is stored in the Vals array, and the ordinal of the key corresponds to the position of the subscript.
It is important to note that, when stored, the system masknull the value, and when the unmasknull is processed on the return, we then look at the relevant code:
Private Static FinalObject NULL =NewObject () { Public inthashcode () {return0; } PublicString toString () {return"Java.util.EnumMap.NULL"; } }; PrivateObject Masknull (object value) {return(Value = =NULL?null:value); } PrivateV unmasknull (Object value) {return(V) (value = = NULL?)NULL: Value); }
As you can see, the purpose of this method is to replace the null object if the target value is null, so why do you do this?
This is because, in the Vals array, the default is no value, and this is represented by NULL. So, Enummap itself is a support value of NULL, if you do not do any processing to set Vals to NULL, it cannot be distinguished from the absence of a value, so this way to implement the representation of a null value.
3. Take the value
As with the stored value, the value is relatively simple, as follows:
Public V get (Object key) { return (Isvalidkey (key)? ) NULL ); }
Compared to HashMap, this value operation is directly located, very fast.
4. Key existence judgment
As we said earlier, when initializing the array of key is actually determined, does it mean that all keys exist? See implementation:
Public Boolean ContainsKey (Object key) { returnnull; }
Visible, if a key corresponding to the subscript does not set a value, the system considers that the key is not included.
Iii. Summary
From the previous analysis we can see that the implementation of ENUMMAP is very simple, and access is very efficient, if our business scenario is able to set a number of fixed key values, then such key will be very efficient.
Container--enummap