JavaSE-集合Map
- Collection使用
- List使用
- ArrayList、LinkedList、Vector使用
- 完成Map接口及应用
- 完成HashMap理解及应用
- 完成TreeMap理解及应用
- 完成泛型理解及应用
三、本章目标
- 掌握Map接口及使用
- 掌握HashMap理解及使用
- 掌握TreeMap理解及应用
- 掌握泛型理解及应用
-
知识点
1、 Map接口
Map用于保存具有映射关系的数据,因此Map集合里保存两组值。
1. 一组值用于保存key,一组值用于保存value
2. key~value之间存在单向一对一关系,通过指定key可以找到唯一的value值
3. key和value都可以是任何引用类型对象
4. 允许存在value为null,但是只允许存在一个key为null
【常用方法】
方法 | 描述 |
V put(K key, V value) | 将指定的值与此映射中的指定键关联 |
boolean containsKey(Object key) | 如果此映射包含指定键的映射关系,则返回true |
boolean containsValue(Object value) | 如果此映射将一个或多个键映射到指定值,则返回true |
boolean isEmpty() | 如果此映射未包含键-值映射关系,则返回true |
V get(Object key) | 返回指定键所映射的值,如果此映射不包含该键的映射关系,则返回null |
Set<K> keySet() | 返回此映射中包含的键的set集合 |
Collection<V> values() | 返回此映射中包含的值的Collection集合 |
Set<Map.Entry<K,V>> entrySet() | 返回此映射中包含的映射关系的set集合 |
boolean equals(Object o) | 返回指定的对象与此映射是否相等 |
int hashCode() | 返回此映射的哈希码值 |
V remove(Object key) | 如果存在一个键的映射关系,则将其从此映射中移除 |
void clear() | 从此映射中移除映射关系 |
int size() | 返回此映射中的键-值关系数 |
【示例】
使用水浒传的人物姓名:外号演示map的常用方法
1. HashMap类
【特点】
- key无序不可重复
- 底层是哈希表
【哈希表实现原理】
- HashMap实际上是一个"链表的数组"的数据结构,每个元素存放链表头结点的数组,即数组和链表的结合体。
- 当我们往HashMap中put元素的时候,先根据key的hashCode重新计算hash值,根据hash值得到这个元素在数组中的位置(即下标),如果数组该位置上已经存放有其他元素了,那么在这个位置上的元素将以链表的形式存放,新加入的放在链头,最先加入的放在链尾。如果数组该位置上没有元素,就直接将该元素放到此数组中的该位置上。
- 只有相同的hash值的两个值才会被放到数组中的同一个位置上形成链表。
- 如果这两个Entry的key通过equals比较返回true,新添加Entry的value将覆盖集合中原有Entry的value,但key不会覆盖。
【总结】
- HashMap中key的hashCode值决定了<k,v>键值对组成的entry在哈希表中的存放位置。
- HashMap中key通过equals()比较,确定是覆盖key对应的value值还是在链表中添加新的entry。
- 综合前两条,需要重写hashCode()和equals()方法。
【示例】
定义学生类,重写hashCode()和equals()方法。放进HashMap中,key是学号,value是学生对象。
【HashSet回顾】
特点
1. HashSet底层由HashMap实现
2. 无序不可重复
【示例】
定义5个学生,放进HashSet。(根据学号去重)
2. TreeMap
TreeMap是SortedMap接口的实现类,可以根据Key进行排序,HashMap没有这个功能。
【特点】
1. 底层由可排序二叉树实现
2. 不指定比较器默认按照key自然升序,指定比较器按照比较器排序
【示例】
定义5个学生对象,放在treeMap中,按照比较器的规则进行排序
【总结】
TreeMap需要key实现Comparable接口,排序主要看compareTo()方法。
泛型是指所操作的数据类型被指定为一个参数,在用到的时候再指定具体的类型。这种参数类型可以用在类、接口和方法的创建中,分别称为泛型类、泛型接口和泛型方法。
【示例】
1. 定义一个对象池对象,可以根据需求存放各种类型对象。
class ProjectPool<T>{
private List<T> list = new ArrayList<T>();
public void add(T t){
list.add(t);
}
public int size(){
return list.size();
}
}
2. 集合中使用泛型
List<Student> stuList = new ArrayList<Student>();
【总结】
1. 泛型能更早的发现错误,如类型转换错误
2. 使用泛型,那么在编译期将会发现很多之前要在运行期发现的问题
3. 代码量往往会少一些、运维成本减少
4. 抽象层次上更加面向对象
五、总结
见:JavaSE-集合map总结.xmind
六、作业