1 Introduction
We know that Map
is just an interface, it has a variety of implementations, Java is the most commonly used is HashMap
the. And think about this article is another realization: EnumMap
. It is an enumerated type Map
requires its Key values must be an enumeration type.
2 Create your EnumMap
Since it is about enumerated type Map, we first create an enumeration, for subsequent use:
public enum Directions {
NORTH, SOUTH, EAST, WEST
}
2.1 creation of three methods EnumMap
Creating JDK provides EnumMap
a method of three, as follows:
//new EnumMap
EnumMap<Direction, String> enumMap = new EnumMap<>(Direction.class);
enumMap.put(Direction.EAST, "东");
enumMap.put(Direction.SOUTH, "南");
//从EnumMap复制
EnumMap<Direction, String> enumMapCopyEnumMap = new EnumMap<>(enumMap);
assertEquals(enumMap, enumMapCopyEnumMap);
//从Map复制
Map<Direction, String> hashMap = Maps.newHashMap();
hashMap.put(Direction.EAST, "东");
hashMap.put(Direction.SOUTH, "南");
EnumMap<Direction, String> enumMapCopyHashMap = new EnumMap<>(hashMap);
assertEquals(enumMap, enumMapCopyHashMap);
(1) using the
new EnumMap()
time method, andHashMap
different, it must pass an enumerated type to create objects;(2) from the
EnumMap
copy, then the parameter is passedEnumMap
;(3) from
Map
copying, incoming parametersMap
, but it must be requested Key type enumeration type.
2.2 Smart Guava
In fact, can combine the above three cases, is actually two ways:
(1) Use
new EnumMap(Class<K> keyType)
(2) Use
new EnumMap(Map<K, ? extends V> m)
Smart Guava
will only provide these two methods, as follows:
//使用Guava创建
EnumMap<Direction, String> enumMapGuava = Maps.newEnumMap(Direction.class);
enumMapGuava.put(Direction.SOUTH, "南");
assertEquals(1, enumMapGuava.size());
enumMapGuava = Maps.newEnumMap(enumMap);
assertEquals(enumMap, enumMapGuava);
3 Basic Operations
The method of providing the same Map of course, easy to operate, as follows:
@Test
public void operations() {
EnumMap<Direction, String> map = Maps.newEnumMap(Direction.class);
//增加
map.put(Direction.EAST, "东");
map.put(Direction.SOUTH, "南");
map.put(Direction.WEST, "西");
//查询
assertTrue(map.containsKey(Direction.EAST));
assertFalse(map.containsKey(Direction.NORTH));
//删除
map.remove(Direction.EAST);
assertFalse(map.containsKey(Direction.EAST));
assertFalse(map.remove(Direction.WEST, "北"));
assertTrue(map.remove(Direction.WEST, "西"));
//清空
map.clear();
assertEquals(0, map.size());
}
Of particular note is the Delete method, Key and Value can be passed two parameters, map.remove(Direction.WEST, "西")
when the key-value pairs match, you can delete success; map.remove(Direction.WEST, "北")
the match fails, it will not be deleted.
4 collection view
4.1 orderliness
As with the Map function interface provided, EnumMap
it can return all of its Values, Keys and Entry and so on. But the HashMap
difference is that EnumMap
the return of view is in order, this order is not inserted in order, but the order of the enumeration definition. code show as below:
EnumMap<Direction, String> map = Maps.newEnumMap(Direction.class);
map.put(Direction.EAST, "东");
map.put(Direction.SOUTH, "南");
map.put(Direction.WEST, "西");
map.put(Direction.NORTH, "北");
//返回所有Value
Collection<String> values = map.values();
values.forEach(System.out::println);
//返回所有Key
Set<Direction> keySet = map.keySet();
keySet.forEach(System.out::println);
//返回所有<Key,Value>
Set<Map.Entry<Direction, String>> entrySet = map.entrySet();
entrySet.forEach(entry -> {
System.out.println(entry.getKey() + ":" + entry.getValue());
});
Output results are as follows:
北
南
东
西
NORTH
SOUTH
EAST
WEST
NORTH:北
SOUTH:南
EAST:东
WEST:西
This sequence and indeed we define enumeration order is the same, regardless of the order added.
4.2 Linkage
In addition to ordering, EnumMap
the returned collection view Another point of difference is the linkage that indeed affect the whole body. Wherein a change, followed further changed. Look at the code you will understand:
//Values、keySet、entrySet改变会影响其它
values.remove("东");
assertEquals(3, map.size());
assertEquals(3, keySet.size());
assertEquals(3, entrySet.size());
keySet.remove(Direction.WEST);
assertEquals(2, map.size());
assertEquals(2, values.size());
assertEquals(2, entrySet.size());
entrySet.removeIf(entry -> Objects.equals(entry.getValue(), "北"));
assertEquals(1, map.size());
assertEquals(1, keySet.size());
assertEquals(1, values.size());
//Map的改变会影响其它视图
map.clear();
assertEquals(0, values.size());
assertEquals(0, keySet.size());
assertEquals(0, entrySet.size());
5 Performance
Performance is we chose EnumMap
one of the main reasons, why it would be more than good performance HashMap
even good? It can be learned by looking at the source code:
(1) The bottom layer is to store the data by two arrays, one of the discharge Keys, a discharge Values;
(2) because the Key value is an enumerated type, that is beginning to determine the number of elements, so creating a EnumMap
time, storing data on the array size has been determined, without regard to performance problems caused by the subsequent expansion.
(3) the enumeration itself is a fixed sequence, by Enum.ordinal()
a method for obtaining the order, this will be inserted as a query to the index, rather than computing HashCode
, performance will be faster. This order is the array index. This is also EnumMap
the view of the collection are the reasons for order.
(4) because the fixed size, regardless of load factor, there is no problem of hash collision, a small space complexity.
6 Conclusion
This article describes EnumMap
as a Map
special realization of the creation, use, and view a collection of performance analysis and found that it really is superior to others. When our Key value is an enumeration, you may wish to try EnumMap
, the performance will be better Oh.
Welcome to public concern number < pumpkin slow, said >, you will continue to update ...
More books, more sharing; and more writing, more than finishing.