您的位置:首页 > 编程语言 > Java开发

java集合汇总-Map-Set-HashMap等的区别与联系<未完待续>

2016-04-04 20:06 471 查看
一,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具体是怎么实现线程安全的呢,肯定不可能是每个方法加synchronized,那样就变成了HashTable。

从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,也是有一定道理的。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: