Map保存具有映射关系的数据。Map内部维护Entry接口,接口内部维护操作key和value的方法。Map的实现类中会包含Node内部类(实现Entry接口),Node内部类包含key和value属性,所有对key和value的操作实际是对内部对象Node类属性的操作.
Map接口内部部分结构如下:
HashMap的内部部分结构如下:
Object get(Object key)源码如下:通过key遍历所有的Node对象获取value
public V get(Object key) {
Node<K,V> e;
return (e = getNode(hash(key), key)) == null ? null : e.value;
}
将Map的key和value拆开看,所有的key可以看做一个Set(无序,不能重复),value可以看做List(可重复,通过key来索引)
Map常见方法如下:
- void clear():删除所有元素
- boolean containsKey(Object key)
- boolean containsValue(Object value)
- Set entrySet():返回Map内部所有的entry,并组成Set集合
- Set keySet():返回所有key组成的Set集合
- Object get(Object key)
- Object put(Object key,Object value)
- Object remove(Object key)
- boolean isEmpty()
- int size()
内部接口Entry提供的方法如下:
- Object getKey()
- Object getValue()
- Obejct setValue(Object value)
HashMap类和Hashtable类
HashMap和Hashtable区别:
- Hashtable是线程安全的,多线程情况下,性能较低;HashMap不是线程安全的
- Hashtable的key和value不允许为null,如果试图将null添加到Hashtable中,会抛出NullPointerException;HashMap的key和value允许为null,但key因为不能重复,因此只能有一个null作为key
如何判断key或value是否相等?
HashMap和Hashtable判断标准相同。key判断是否相同的标准和HashSet一致,key的int hashCode()返回是否相同,且boolean equals(Object o)是否返回true;value判断是否相等只通过equals()比较。
HashMap和Hashtable存储
当向HashMap中添加元素时,调用key的int hashCode()返回值,决定在内存中的存储位置,如果该位置没有元素,则将entry存入;如果有元素,则将两个元素存在一起,并通过链表连接。
HashMap和Hashtable存储规则相同
LinkedHashMap类
LinkedHashMap时HashMap的子类,LinkedHashMap不同于 HashMap的点是LinkedHashMap使用链表维护内部entry的顺序,使得内部元素有序。也是因为内部维护链表,导致LinkedHashMap比HashMap性能略低
Properties读写配置文件
Properties是Hashtable的子类,用于读写配置文件。相当于Map<String,String>,常用方法如下:
- String getProperty(String key)
- String getProperty(String key,String defaultValue)
- Object setProperty(String key,String value)
- void load(InputStream stream):通过流加载配置文件信息到Properties
- void store(OutputStream stream,String comment):将Properties中键值对存到配置文件中,comment表示备注
SortedMap接口和TreeMap类
和TreeSet类似,TreeMap采用红黑树结构存储,key-value作为树的节点。存储时需要根据key进行排序,排序方式如下:
- 自然排序:key对应的类实现Comparable接口,重写int compareTo(Object o)方法
- 自定义排序:创建TreeMap传入Comparator对象,该对象的int compare(Object o1,Object o2)负责比较元素
因为TreeMap是有序的,所有提供了访问第一个、前一个 、后一个、最后一个元素的方法
各个Map比较
具体使用Map时,根据需要使用Map接口的实现类:
- HashMap所有Map实现类性能最佳
- 如果需要线程安全的Map可使用Hashtable,或构造线程同步的HashMap
- 如果需要有序的可使用LinkedHashMap
- 如果需要排好序的使用TreeMap,因为TreeMap需要排序,因此性能很差,特别是插入和删除时
Collections工具类
Java提供了操作Set/List/Map集合的工具类,提供了大量的方法对集合进行排序、查询、修改等操作;还提供了对集合对象实现同步的方法。可以通过源码了解一下。