Java 基础:Map的一家

0.Java中的集合框架

1.Map--接口

public interface Map<K,V>

包:java.util.Map

Map提供了一种映射关系,其中的元素是以键值对(key-value)的形式存储的,能够实现根据key快速查找value;

Map中的键值对以Entry类型的对象实例形式存在;

键(key值)不可重复,value值可以重复,一个value值可以和很多key值形成对应关系,每个建最多只能映射到一个值。

Map支持泛型,形式如:Map<K,V>

Map中使用put(K key,V value)方法添加

给定一个键和一个值,你可以将该值存储在一个Map对象. 之后,你可以通过键来访问对应的值。

当访问的值不存在的时候,方法就会抛出一个NoSuchElementException异常.

当对象的类型和Map里元素类型不兼容的时候,就会抛出一个 ClassCastException异常。

当在不允许使用Null对象的Map中使用Null对象,会抛出一个NullPointerException 异常。

当尝试修改一个只读的Map时,会抛出一个UnsupportedOperationException异常。

2.HashMap--实现类

public class HashMap<K,V> extends AbstractMap<K,V>
    implements Map<K,V>, Cloneable, Serializable

包:java.util.HashMap

HashMap是Map的一个重要实现类,也是最常用的,基于哈希表实现

HashMap中的Entry对象是无序排列的

Key值和value值都可以为null,但是一个HashMap只能有一个key值为null的映射(key值不可重复)

3.Hashtable--实现类

public class Hashtable<K,V>
    extends Dictionary<K,V>
    implements Map<K,V>, Cloneable, java.io.Serializable 

HashTable 是以数组和单向链表结合的存储形式;

存储元素时,key通过hash映射函数得到在HashTable存储数组中的位置;

该位置存放的是hash值一致的单向链表的首元素;

新的元素存储到该位置指向的列表中;

数组存储哈希后的key,哈希值相同,则使用链表解决哈希碰撞,放到链表中。

Hashtable是遗留类,很多映射的常用功能与HashMap类似,不同的是它承自Dictionary类,并且是线程安全的,

任一时间只有一个线程能写Hashtable,并发性不如ConcurrentHashMap,因为ConcurrentHashMap引入了分段锁。

Hashtable不建议在新代码中使用,不需要线程安全的场合可以用HashMap替换,需要线程安全的场合可以用ConcurrentHashMap替换。

4.ConcurrentHashMap---实现类

public class ConcurrentHashMap<K,V> extends AbstractMap<K,V>
    implements ConcurrentMap<K,V>, Serializable

包:java.util.concurrent.ConcurrentHashMap

ConcurrentHashMap允许并发的读和线程安全的更新操作

在执行写操作时,ConcurrentHashMap只锁住部分的Map

并发的更新是通过内部根据并发级别将Map分割成小部分实现的

高的并发级别会造成时间和空间的浪费,低的并发级别在写线程多时会引起线程间的竞争

ConcurrentHashMap的所有操作都是线程安全

ConcurrentHashMap返回的迭代器是弱一致性,fail-safe并且不会抛出ConcurrentModificationException异常

ConcurrentHashMap不允许null的键值

可以使用ConcurrentHashMap代替HashTable,但要记住ConcurrentHashMap不会锁住整个Map

5.HashMap与Hashtable

HashTable和HashMap采用相同的存储机制,二者的实现基本一致,不同的是:

1、HashMap是非线程安全的,HashTable是线程安全的,内部的方法基本都是synchronized。

2、HashTable不允许有null值的存在。

 

3、因为线程安全的问题,HashMap效率比HashTable的要高。

 

在HashTable中调用put方法时,如果key为null,直接抛出NullPointerException。其它细微的差别还有,比如初始化Entry数组的大小等等,但基本思想和HashMap一样。

 

6.HashTable和ConcurrentHashMap

ConcurrentHashMap是线程安全的HashMap的实现。

同样是线程安全的类,它与HashTable在同步方面有什么不同呢?

之前我们说,synchronized关键字加锁的原理,其实是对对象加锁,不论你是在方法前加synchronized还是语句块前加,锁住的都是对象整体

但是ConcurrentHashMap的同步机制和这个不同,它不是加synchronized关键字,而是基于lock操作的,

这样的目的是保证同步的时候,锁住的不是整个对象。

事实上,ConcurrentHashMap可以满足concurrentLevel个线程并发无阻塞的操作集合对象。

 

ConcurrentHashMap基于concurrentLevel划分出了多个Segment来对key-value进行存储,从而避免每次锁定整个数组,在默认的情况下,允许16个线程并发无阻塞的操作集合对象,尽可能地减少并发时的阻塞现象。

在多线程的环境中,相对于HashTable,ConcurrentHashMap会带来很大的性能提升!

 

 

 

部分内容参考:http://www.cnblogs.com/wang-meng/p/5808006.html

原文地址:https://www.cnblogs.com/fdzang/p/9675677.html