浅谈java集合类(二)【Map】

时间:2022-09-17 23:27:47

上一节,我们聊了聊List,接下来,我们来看看Map接口。

Map是一种Key,value的存储的结构,也就是说,我们可以通过key来找到value,他们之间是一一映射的。Map的主要实现类有:HashMap,TreeMap...

我们先来看看他的主要方法:

V get(Object key);
//获取与key相对应的值。如果映射表中没有key所映射的值,则返回null
v put(K key, V value);
//将这对键值存入映射表中,如果映射表已经存在该值,则覆盖原来的value,并返回它;如果以前不存在该值,则返回null,需要一直假如jvm不支持key或者value为null的话,将会报错.
void putAll(Map<? extends K, ? extends v>entries)
//向映射表中添加传入映射表中的所有元素
boolean containsKey(Object key);
//判断是否已经存在该key
boolean containsValue(Object value)
//判断是否已经存在该value
Set<Map.Entry<K,V>>entrySet();
//返回Map.Entry对象的集视图,即表中的键值对。可以从这个集中删除元素,并会在原映射表删除它,但是不能添加。
Set<K> keySet();
//返回key的set集,我们能够通过这个集把它删除,但不能添加
Collection<V> values();
//返回映射表中所有值的集合。可以从中删除元素,但是不能添加


下面我们来看看它的主要实现类:
HashMap类

这基本上是我们使用最多的类了, 首先他的数据结构就是和我们学习数据结构hash表几乎是一样的。它是对key进行散列计算,通过调用hashCode()计算key的hashCode,再确认,值插入的位置,当我们插入的值足够多的时候,效率有所下降,无论是插入还是查询,当然我们类的实现者应经考虑到这个问题了,所以,类里有一个填装因子的值,系统默认是75%,使用了插入值占比超过总数的填充因子时,会自动扩容,当然我们也可以自己设置它的值。不仅如此,我们还可以一开始的桶的数量,一般我们将它设置为预计元素的75%~150%,它的默认值是16。看到这,我们有没有觉得它和另外的一个元素比较像呢。的确他就是ArrayList。因此,我们最好设置估计他们的初始大小,以提高效率。

好了,我们来总结一下他的优缺点:

优点:1.插入,查询效率很高

   2.可以自动扩容

缺点:1.需要额外的计算hashCode

   2.使用不当会浪费好多空间

   3.不能有序的,能过还原插入的顺序

我们看看他的方法:

V get(Object Key)
//返回值对应的值
V put(K key,V value)
//插入键值,若已经插在该键值,将对原来进行覆盖,并返回被覆盖的值,若不存在,则直接插入该键值并返回null

TreeMap类

当我们觉得Hashmap类足够优异的时候,还有什么需求呢。没错,那就是按照一定顺序或者规则排序。而TreeMap就这样一种集合,它实现了SortedMap。

我们该怎么使用呢,我们可以在初始化的时候,一个比较器,也就是自己实现一个Comparator<T>接口。当没有传入这个接口时,该类会自动调用传入类型的compareTo方法,该方法继承自Comparable类。假如,又没有传入Comparator,传入类有没有实现Comparable接口,TreeMap根本没法进行比较,根本不知道该按什么规则进行排序,所以,在会报错。

下面我们看看它的构造方法和主要接口:

TreeMap(Comparator<? super K>c)
//构造一个树映射表,并使用一个指定的比较器进行对值进行比较
TreeMap(Map<? extends K,? extends V>entries)
//构造一个树映射,并将映射表中所有数据添加到树映射表
TreeMap(SortedMap<? extends K, ? entends V> emtris)
//与上面基本相同
Hashtable类

与Vector在List中的地位差不多,他也是JDK1.0时就有的,是一个比较古老的散列映射表,他也是同步的,它和HashMap最为类似,同样,因为实现了同步的方法,所以他的性能比HashMap是稍微低一点的。

好了,总的来说,假如你没有比较特殊的需求,我们一概多使用HashMap的,假如你需要自己的映射表有顺序的排列,那么TreeMap最为合适,假如多线程那我们也同样留着后面一块来说说。