Map的常用实现类:
- HashMap 采用哈希表算法,此时Map中的key不保证添加的先后顺序,key值不允许重复。判断可以的值是否重复的方法,key1和key2的equals为true,并且hashcode相等
- LinkedHashMap: 采用链表和哈希表算法,此时的Map会按照添加的先后顺序进行排序。Key值不允许重复,key判断重复的标准是: key1和key2的equals为true,并且hashcode相等
- TreeMap: 采用红黑树算法,此时的Map按照自然顺序和定制排序进行排序,key不允许重复,key判断重复的标准是:compareTo/compar的返回值是否为0.
- Hashtable: 采用哈希表算法,是HashMap的前身,所有的方法都使用了synchronized修饰符,线程安全的,但是性能相对较低。
- Properties: Hashtable的子类,此时要求key和value都是String类型。采用加载资源文件(properties文件)
注:HashMap和TreeMap以及LinkedHashMap都是线程不安全的,但是性能要求较高。
解决线程安全问题的方法
Map temps= Collections.synchronizedMap(maps);
HashMap的详解
是Map的实现类,底层采用的哈希表算法,key值不允许重复,非线程安全,不保证key添加的先后顺序。
以上只是HashMap的简单了解,要想深入的了解,必须要读java里面的源代码。
HashMap的初始化大小16,最大容量为2^30=1073741824(10亿)
负载因子,就是当map集合的容量已经用到当前大小的3/4时,map就会进行扩容。例如(当前大小16,当使用量达到12时,就是自动扩容)。
transient int size; 记录HashMap的键值对个数
final float loadFactor; 装载因子,用来衡量HashMap的装满程度。默认值(static final float DEFAULT_LOAD_FACTOR = 0.75f;)除了,以上的变量还有一个变量与之密切相关,capacity 容量,默认值(static final int DEFAULT_INITIAL_CAPACITY = 16);那么有人便会问size和capacity之间是什么关系?
我们首先假设HashMap是一个桶Size便是桶已经装了多少元素。Capacity就是这个桶“当前”最多可以装多少元素。当达到临界值时,会自动扩容,为当前容量的两倍,加入是16个,达到临界值12时,便扩容(2*16)到32
HashMap中提供了构造方法,用于自定义初始化容量,初始化负载因子。提供了3中方法。
1、同时自定义初始化容量和负载因子。
示例 :
Map<String, String> maps2 = new HashMap<String, String>(1000,0.85f);
2、自定义初始化容量,负载因子默认为0.75
示例:Map<String, String> maps3 = new HashMap<String, String>(100000);
3、默认初始化容量16,负载因子0.75
关于hashcode和equals问题。
如果equals匹配,则hashcode一定相等。如果hashcode相等,equals不一定相等。