一,Map接口
Map、Set、HashMap都是集合,关于集合,需要强调一点是:Collection接口是集合的“始祖”,除了数组,所有的集合都是直接或者间接继承或或者实现了Collection接口。
Map接口源代码
public interface Map {
//查询操作方法
int size();
boolean isEmpty();
boolean containsKey(Object key);
boolean containsValue(Object value);
V get(Object key);
//修改操作方法
V put(K key, V value);
V remove(Object key);
void putAll(Map extends K, ? extends V> m);
void clear();
Set keySet();
Collection values();
Set> entrySet();
interface Entry {
K getKey();
V getValue();
V setValue(V value);
boolean equals(Object o);
int hashCode();
}
boolean equals(Object o);
int hashCode();
}
二,HashMap:
基于哈希表的 Map 接口的实现。此实现提供所有可选的映射操作,并允许使用 null 值和 null 键。(除了非同步和允许使用 null 之外,HashMap 类与 Hashtable 大致相同。)此类不保证映射的顺序,特别是它不保证该顺序恒久不变。
1,HashMap不是线程安全的;2,HashMap允许key为null;
3,HashMap允许value为null;
三,HashTable
1,Hashtable的方法是同步的,是线程安全的;
2,Hashtable不允许key为null;
3,Hashtable不允许value为null;
四,LinkedHashMap
public class LinkedHashMap<K, V> extends HashMap<K, V> implements Map<K, V>
对于LinkedHashMap而言,它继承与HashMap、底层使用哈希表与双向链表来保存所有元素。其基本操作与父类HashMap相似,它通过重写父类相关的方法,来实现自己的链接列表特性。
LinkedHashMap采用的hash算法和HashMap相同,但是它重新定义了数组中保存的元素Entry,该Entry除了保存当前对象的引用外,还保存了其上一个元素before和下一个元素after的引用,从而在哈希表的基础上又构成了双向链接列表。
LinkedHashMap是HashMap的一个子类,它保留插入的顺序,如果需要输出的顺序和输入时的相同,那么就选用LinkedHashMap。LinkedHashMap实现与HashMap的不同之处在于,后者维护着一个运行于所有条目的双重链接列表。此链接列表定义了迭代顺序,该迭代顺序可以是插入顺序或者是访问顺序。
五,ConcurrentHashMap
ConcurrentHashMap是同步HashMap,是一种线程安全,并且高效的HashMap。HashmMap不是线程安全的,而ConcurrentHashMap是线程安全的;Hashtable是线程安全的,
但是效率很低,ConcurrentHashMap也是线程安全的,效率高于Hashtable。
ConcurrentHashMap实现线程安全,用到了很多经典的算法和思路,volatile关键字就是其中之一。
关于ConcurrentHashMap这个类的说明,这里不再赘述,贴上源代码中的官方说明,有兴趣的朋友可以读一下。
从ConcurrentHashMap代码中可以看出,它引入了一个“分段锁”的概念,具体可以理解为把一个大的Map拆分成N个小的HashTable,根据key.hashCode()来决定把key放到哪个HashTable中。
在ConcurrentHashMap中,就是把Map分成了N个Segment,put和get的时候,都是现根据key.hashCode()算出放到哪个Segment中:以上就是ConcurrentHashMap的工作机制,通过把整个Map分为N个Segment(类似HashTable),可以提供相同的线程安全,但是效率提升N倍,默认提升16倍。
/**
* A hash table supporting full concurrency of retrievals and
* adjustable expected concurrency for updates. This class obeys the
* same functional specification as {@link java.util.Hashtable}, and
* includes versions of methods corresponding to each method of
* <tt>Hashtable</tt>. However, even though all operations are
* thread-safe, retrieval operations do <em>not</em> entail locking,
* and there is <em>not</em> any support for locking the entire table
* in a way that prevents all access. This class is fully
* interoperable with <tt>Hashtable</tt> in programs that rely on its
* thread safety but not on its synchronization details.
*
* <p> Retrieval operations (including <tt>get</tt>) generally do not
* block, so may overlap with update operations (including
* <tt>put</tt> and <tt>remove</tt>). Retrievals reflect the results
* of the most recently <em>completed</em> update operations holding
* upon their onset. For aggregate operations such as <tt>putAll</tt>
* and <tt>clear</tt>, concurrent retrievals may reflect insertion or
* removal of only some entries. Similarly, Iterators and
* Enumerations return elements reflecting the state of the hash table
* at some point at or since the creation of the iterator/enumeration.
* They do <em>not</em> throw {@link ConcurrentModificationException}.
* However, iterators are designed to be used by only one thread at a time.
*
* <p> The allowed concurrency among update operations is guided by
* the optional <tt>concurrencyLevel</tt> constructor argument
* (default <tt>16</tt>), which is used as a hint for internal sizing. The
* table is internally partitioned to try to permit the indicated
* number of concurrent updates without contention. Because placement
* in hash tables is essentially random, the actual concurrency will
* vary. Ideally, you should choose a value to accommodate as many
* threads as will ever concurrently modify the table. Using a
* significantly higher value than you need can waste space and time,
* and a significantly lower value can lead to thread contention. But
* overestimates and underestimates within an order of magnitude do
* not usually have much noticeable impact. A value of one is
* appropriate when it is known that only one thread will modify and
* all others will only read. Also, resizing this or any other kind of
* hash table is a relatively slow operation, so, when possible, it is
* a good idea to provide estimates of expected table sizes in
* constructors.
*
* <p>This class and its views and iterators implement all of the
* <em>optional</em> methods of the {@link Map} and {@link Iterator}
* interfaces.
*
* <p> Like {@link Hashtable} but unlike {@link HashMap}, this class
* does <em>not</em> allow <tt>null</tt> to be used as a key or value.
*
* <p>This class is a member of the
* <a href="{@docRoot}/../technotes/guides/collections/index.html">
* Java Collections Framework</a>.
*
* @since 1.5
* @author Doug Lea
* @param <K> the type of keys maintained by this map
* @param <V> the type of mapped values
*/
不常用的:
HashSet
TreeSet
SortedSet
EnumMap
SortedMap
TreeMap
HashMap类中的方法:
void clear() //从此映射中移除所有映射关系。
Object clone() //返回此 HashMap 实例的浅表副本:并不复制键和值本身。
boolean containsKey(Object key) //如果此映射包含对于指定键的映射关系,则返回 true。
boolean containsValue(Object value) //如果此映射将一个或多个键映射到指定值,则返回 true。
Set<Map.Entry<K,V>> entrySet() //返回此映射所包含的映射关系的 Set 视图。
V get(Object key) //返回指定键所映射的值;如果对于该键来说,此映射不包含任何映射关系,则返回 null。
boolean isEmpty() //如果此映射不包含键-值映射关系,则返回 true。
Set<K> keySet() //返回此映射中所包含的键的 Set 视图。
V put(K key, V value) //在此映射中关联指定值与指定键。
void putAll(Map<? extends K,? extends V> m) //将指定映射的所有映射关系复制到此映射中,这些映射关系将替换此映射目前针对指定映
射中所有键的所有映射关系。
V remove(Object key) //从此映射中移除指定键的映射关系(如果存在)。
int size() //返回此映射中的键-值映射关系数。
Collection<V> values() //返回此映射所包含的值的Collection 视图。
HashMap的数据结构:HashMap用了一个名字为table的Entry类型数组;数组中的每一项又是一个Entry链表。
最后,我们说一下一个特殊的集合,数组(Array)
什么是数组?
百科定义:所谓数组,就是相同数据类型的元素按一定顺序排列的集合。也可以这样说:把有限个类型相同的元素,用一个名字命名,然后用
编号区分,这样的变量集合就叫数组,这个名字称为数组名,编号称为下标。數組是大小固定的數據結構。數組位於堆內存的方法區。
要点:
* 数组是集合;
* 数组的长度是固定的;
* 数组是有顺序的;
数组号称java界效率最高的数据结构。很多欧美的java大师都建议,我们尽量使用数组代替ArrayList和Vector,也是有一定道理的。