1 Map集合N016
1.1 Map接口
【
• 实现Map接口的集合类用来存储"键-值"映射对。
• JDK API中Map接口的实现类常用的有
– HashMap
– TreeMap
– Hashtable (不常用)
•Map实现类中存储的"键-值"映射对是通过键来唯一标识,Map底层的"键"是用Set来存放的。
•所以存入HashMap中的映射对的"键"如果是自定义的类,应该重写hashCode()和equals()方法。
–常用String作为Map的"键"。
】
Map接口中定义的一些常用方法:
【
V put(K key, Vvalue)//将指定的"键-值"对存入Map中
V get(Object key);//返回指定键所映射的值
V remove(Objectkey);//根据指定的键把此"键-值"对从Map中移除。
boolean containsKey(Object key);//判断此Map是否包含指定键的"键-值"对。
boolean containsValue(Object value);//判断此Map是否包含指定值的"键-值"对。
boolean isEmpty();//判断此Map中是否有元素。
int size();//获得些Map中"键-值"对的数量。
void clear();//清空Map中的所有"键-值"对。
Set keySet();//返回此Map中包含的键的Set集。
Collection values();//返回此Map中包含的值的Collection集。值是可重复的.
】
HashMap:
【
HashMap内部对"键"用Set进行散列存放。所以根据"键"去取"值"的效率很高。
它是使用频率最高的一个集合。
补充:封装类对象的hashCode()
】
Hashtable与HashMap的不同(笔试常考)
【
Hashtable是JDK1.0就有了, HashMap是JDK1.2引入的,操作大多跟Hashtable相同,建议使用HashMap.
Hashtable (注意大小写)
是同步的(线程安全的);
不能有null键,也不能有null值,否则运行时出空指针异常;
基于陈旧的Dictionary类 ,有contains() 方法,用于测试此映射表中是否存在指定值,等同于HashMap类中的containsValue()(本类中也有)
HashMap
是不同步的(线程非安全的);
能存储最多一个null键,任意多个null值;
有containsKey(),containsValue()方法,没有contains() 方法
继承AbstractMap
】
TreeMap:
【
TreeMap内部使用红黑树结构对"key"进行排序存放,所以放入TreeMap中的"key-value"对的"key"必须是"可排序"的。
TreeMap()使用键的自然顺序构造一个新的、空的树映射。
TreeMap(Comparator comparator) 构造一个新的、空的树映射,该映射根据给定比较器进行排序。
】
Map.Entry接口:
【
Map.Entry是Map中内部定义的一个static接口,专门用来保存keyvalue的内容。
】
Map接口输出:
【
对于Map接口来说,其本身是不能直接使用迭代进行输出的,因为Map中的每一个位置存放的是一对值(keyvalue),而Iterator中每次只能找到一个值。所以如果非要使用迭代进行输出的话,要按照以下操作步骤完成:
1.将Map的实例通过entrySet()方法变为Set接口对象
2.通过Set接口的实例的iterator()将Iterator实例化
3.通过Iterator迭代输出,每个内容都是Map.Entry的对象
4.通过Map.Entry进行keyvalue的分离。getKey,getValue
Map大多时候用于存放和查找,遍历输出属于少数操作。
Set> set= map.entrySet();
Iterator>it = set.iterator();
while(it.hasNext()){
Entry entry = it.next();
Studentkey = entry.getKey();
Stringvalue = entry.getValue();
}
】
选择适合的集合:
【
选择标准:
存放要求
无序,无下标,不能随机访问-Set
有序,有下标,可以随机访问-List
不可重复--Set
可重复--List
"key-value"对,较多存放和查询,较少遍历-Map
读和改(插入删除)的效率
Hash*-两者都最高
ArrayList-读(指定下标随机访问)快,插入/删除元素慢
LinkedList-读(指定下标随机访问)慢,插入/删除元素快
】
1.2 总结:
【
•Collection接口
•Iterator接口
•Comparable接口(自然顺序比较,TreeSet,TreeMap)、Comparator接口(自定义比较器, TreeSet,TreeMap)
•Set、List、Map接口
•Collections类
•ArrayList、LinkedList、Vector类
•HashSet、LinkedHashSet、TreeSet类
•HashMap、Hashtable、TreeMap类
•集合的泛型操作(JDK5.0)
•用增强的for循环(JDK5.0)遍历Collection
】
集合框架:保存对象
【
问:集合框架和数组的区别?
1、集合框架的大小是可变的,而数组的大小是固定的
2、集合框架只能存储引用数据类型(对象),而数组能够存储引用数据类型,也能存储基本数据类型
问:集合框架能否保存基本数据类型
不能,但是可以保存基本数据类型的数值,在保存的时候会自动装箱成对应包装类(JDK1.5)
】
Collection :单列集合
|--List接口:有序(存取迭代的顺序),元素可重复
|--ArrayList
|--LinkedList
|--Vector(线程同步的)
|--Set接口:无序,元素不可重复
|--HashSet
|--TreeSet
Map接口:双列集合(Key-Value)
|--HashMap
|--TreeMap
|--Hashtable(线程同步的)
总结:
1、如果存储的数据不多,我们习惯List使用ArrayList,Set使用HashSet,Map使用HashMap
2、如果没有用到类中的特有方法,那么在定义引用类型的时候一般使用接口类型,以便于增强代码的扩展性和后期的维护性
【
】
1.3 Map映射对
Map 映射对,里面存放的是一对对的元素,以键值对形式存在
键key
值value
Map是一个接口,有一个重要的实现类:
HashMap
重要方法:
put(K key,V value)放入键值对,键的类型为K,值的类型为V
比如:定义创建HashMap,它的put方法就变为
put(Stringkey,Integer value)键的类型是String,值为Integer
V get(K key)根据键拿出值,键类型为K,返回的值的类型为V,如果根本不包含这个键,就返回null
比如:定义创建HashMap,它的get方法就变为
Integer get(Stringkey)
如果已经存在某个键,又put了进去相同键的键值对,那么后加入的值会覆盖之前的值,可以这么说,Map中键值对的键是不可重复的,如果存入相同的键,后面的值后覆盖前面的值。
size()返回大小,或者说键值对个数
1.4 遍历HashMap
遍历HashMap?
entrySet()返回一个Set,Entry封装了键和值,遍历这个Set就能遍历所有的键值对了
(HashTable和HashMap用法、特性差不多,但是键和值不可以是null,是线程安全;HashMap的键值可以是null,并且线程不安全)
(Set的元素可以是null、List的元素也可以是null)
HashSet内部的实现是一个HashMap
HashMap中封装了Entry的数组
1.5 TreeMap
以树作为具体实现的方式的Map
它的元素必须可比较,或者给这个TreeSet传入一个比较器对象作为比较逻辑,排序和比较都是针对键,值不管
1、键实现Comparable接口
2、通过构造方法传入一个Comparator的实现类对象
方法和HashMap差不多
put(K key,V value)放入键值对
V get(K key)根据键拿出值
entrySet()返回一个Entry元素的Set对象,用来遍历这个Map
TreeSet中封装了TreeMap
TreeMap封装了二叉树(红黑树,解决普通二叉树不平衡的缺点)
1.6 LinkedHashMap
LinkedHashMap 使用Hash表作为存储结构,放入的顺序可以保持下来
LinkedHashSet 是有序的(可以保持元素存入的顺序,所以我们在讲Set的时候并没有说Set是无序)