我们先来看看Map体系的继承树
Map:“键值”对映射的抽象接口。该映射不包括重复的键,一个键对应一个值。
SortedMap:有序的键值对接口,继承Map接口。
TreeMap:有序散列表,实现SortedMap 接口,底层通过红黑树实现。
HashMap:是基于Hash算法实现的散列表。底层采用“数组+链表”实现,一般用于单线程。Key,Value允许Null。
HashTable:是基于Hash算法实现的散列表。底层采用“数组+链表”实现,一般用于多线程。Key,Value不允许Null。
HashMap
HashMap也是我们使用非常多的Collection,它是基于哈希表的 Map 接口的实现,以key-value的形式存在。在HashMap中,key-value总是会当做一个整体来处理,系统会根据hash算法来来计算key-value的存储位置,我们总是可以通过key快速地存、取value。
定义
HashMap实现了Map接口,继承AbstractMap。
public class HashMap<K,V>
extends AbstractMap<K,V>
implements Map<K,V>, Cloneable, Serializabl
构造方法
HashMap提供了三个构造函数:
HashMap():构造一个具有默认初始容量 (16) 和默认加载因子 (0.75) 的空 HashMap。
HashMap(int initialCapacity):构造一个带指定初始容量和默认加载因子 (0.75) 的空 HashMap。
HashMap(int initialCapacity, float loadFactor):构造一个带指定初始容量和加载因子的空 HashMap。
数据结构
为什么,Map能够实现快速的存取,我们知道在Java中最常用的两种结构是数组和模拟指针(引用),几乎所有的数据结构都可以利用这两种来组合实现,HashMap也是如此。实际上HashMap是一个“链表散列”,如下是它数据结构:
从上图我们可以看出HashMap底层实现还是数组,只是数组的每一项都是一条链。当然在Java1.8以后,如果链表长度大于8时,就会自动转为二叉树来储存。
基本存取
** 添加元素**:
V put(K key,V value):添加元素。这个其实还有另一个功能?替换
如果键是第一次存储,就直接存储元素,返回null
如果键不是第一次存在,就用值把以前的值替换掉,返回以前的值
删除元素:
void clear ():移除所有的键值对元素
V remove (Object key):根据键删除键值对元素,并把值返回
获取元素:
Set<Map.Entry<K,V>> entrySet(): 返回一个键值对的Set集合
V get(Object key):根据键获取值
Set keySet():获取集合中所有键的集合
Collection values():获取集合中所有值的集合
HashMap<Integer, String> map = new HashMap<>();
map.put(1,"School");//添加元素
map.put(2,"Home");
map.put(3,"library");
map.put(3,"Game");//相同键值会覆盖
System.out.println(map);
map.remove(3);//删除Key1
System.out.println(map);
map.clear();//清空map
System.out.println(map);
Set<Map.Entry<Inter, String>> entries = map.entrySet();
Set<String> keys = map.keySet();
for(String key:keys){
String value = map.get(key);
System.out.println(key+"==="+value);
}
TreeMap
TreeMap 的实现是红黑树算法的实现,所以要了解 TreeMap 就必须对红黑树有一定的了解,但是,我试着了解了一下,发现真的有点复杂,其实也不是太复杂,就是静不下心去看。我感觉跟之前学的数据结构中的二叉查找树差不多,但是,还是有些不同的,因为红黑树需要平衡,所以就有左旋,右旋,和着色一系列的操作。总之比较麻烦,有时间再看看源码去了解一下,在这里我们就了解一下它的用法。
定义
public class TreeMap<K,V>
extends AbstractMap<K,V>
implements NavigableMap<K,V>, Cloneable, java.io.Serializable
TreeMap 继承 AbstractMap,实现 NavigableMap、Cloneable、Serializable 三个接口。其中 AbstractMap 表明 TreeMap 为一个 Map 即支持 key-value 的集合,NavigableMap(更多)则意味着它支持一系列的导航方法,具备针对给定搜索目标返回最接近匹配项的导航方法 。(也就是key索引)。
构造方法
TreeMap(): 默认构造函数。使用该构造函数,TreeMap中的元素按照自然排序进行排列。
TreeMap(Map<? extends K, ? extends V> copyFrom):创建的TreeMap包含Map
TreeMap(Comparator<? super K> comparator):指定Tree的比较器
TreeMap<Integer, String> map = new TreeMap<>();//自然排序
TreeMap<Integer, String> map = new TreeMap<>();//自然排序
map.put(10,"aaaaa");
map.put(9,"bbbbbb");
map.put(1,"vvv");
map.put(4,"dddd");
map.put(2,"qqqq");
map.put(3,"sssad");
for (Integer integer : map.keySet()) {
System.out.println(integer+"=="+map.get(integer));
}
传入自定比较器:
TreeMap<Integer, String> map = new TreeMap<>(new Comparator<Integer>() {
@Override
public int compare(Integer o1, Integer o2) {
return -(o1-o2);
}
});//自然排序
map.put(10,"aaaaa");
map.put(9,"bbbbbb");
map.put(1,"vvv");
map.put(4,"dddd");
map.put(2,"qqqq");
map.put(3,"sssad");
for (Integer integer : map.keySet()) {
System.out.println(integer+"=="+map.get(integer));
}
TreeMap特点
除了具备Map集合的一般特点以外还具备以下特点:
1.键的数据结构是红黑树,可保证键的排序和唯一性
2.排序分为自然排序和比较器排序
3.线程是不安全的效率比较高