map概叙
案例:
学生案例,例如要区分一个学生 往往需要使用到学号,是不能单纯的通过姓名和年龄作区分的
如果采用单个元素的集合 需要查找一个学生的名字,那么需要遍历直到找到为止
由于学号可以用于区分学生信息,那么学号是唯一的
Java提供了一种集合: Map
特点 :
将键映射到值的对象,一个映射不能包含重复的键;并且每个键只能映射一个值.
Map和Collection有何区别?
Map集合储存元素是成对出现的,Map集合的键是唯一的,值是可重复的.
Collection集合储存的元素是单独出现的.Collection的儿子Set的唯一的,List是可重复的.
注意: Map的数据结构值针对键有效,跟值无关
Collection集合的数据结构是针对元素有效
Map集合的功能概叙:
添加功能:
1 2 3
| V put(K key,V value) void putAll(Map<? extends K,? extends V> m)
|
删除功能:
1 2
| void clear() V remove(Object key)
|
判断功能:
1 2 3
| boolean containsKey(Object key) boolean containsValue(Object value) boolean isEmpty()
|
获取功能:
1
| Set<Map.Entry<K,V>> entrySet()
|
首先Map.Entry<K, V> 是一个接口 并且它是map接口里面的一个封闭接口(接口中的接口) jdk1.2
方法:
1 2 3 4 5 6
| equals(Object o) getKey() 返回此项对应的key getValue() 返回此项对应的value hashCode() 返回此映射项的哈希码值 setValue(V value) 用指定的值替换此项对应的值 可选操作 注意: 这里修改值直接对map集合的键值对产生影响,并不是拿出来的就是单独的
|
1 2 3
| V get(Object key) 根据键获取值 Set<K> keySet() 返回此集合中包含的键的set集合 Collection<V> values() 返回此集合中包含的值的Collection集合
|
长度功能
1
| int size() 返回此集合的键值对关系数量
|
map的子类 HashMap
HashMap 键值对的几种情况
1.键值对都是String 由于String的hashCode的特殊情况 故而常量池的同一个String的键唯一性保证
2.键是Integer但是值是String的情况 这里只需要注意一下Integer类型的常量池问题不要混淆 Integer的hashCode方法得到的是数值
这里进而证明了 == 比较的是内存地址 而非hashCode
Integer i1 = new Integer(129);
Integer i2 = new Integer(129); i1 == i2 --> false / i1.hashCode() == i2.hashCode() true
3.键是String但是值是普通对象(Student)
4.键是普通对象但是值是String 如果想要实现对象内容相同值覆盖 那么需要重写hashCode与equals方法
LinkedHashMap的概叙与特点
首先 它是HashMap的子类 Map 接口的哈希表和链接列表实现,具有可预知的迭代顺序。
哈希表保证唯一性 链表保证有序性 它不会因为修改的顺序而影响它元素的先后顺序
TreeMap概叙以及案例
键是红黑树结构,可以保证键的排序和唯一性
案例: 键与值都是String的类型 由于是红黑树结构,故而要实现比较性,要么元素具备比较性实现comparable接口 要么集合具备比较性传入比较器comparator
String实现了comparable接口是先按照字母顺序排序再按字母个数
键是一个普通对象,值是一个String 那么要么普通对象实现comparable接口,要么构造比较器
练习
一、统计字符串中每个字母出现的次数 例如: abcab –> a(2) b(2) c(1)
分析:
方案一 : 定义统计变量,遍历字符串,得到每个字符作判断 对应变量自增即可 最后拼接输出结果
但是这样扩展性很差 而且定义变量也多 比如字母大小写,数字,中文..........
方案二 : 定义一个Map 键是字符 值是统计类型 Integer 并且选择TreeMap 让这些个字符自然排序
拿字符串的每一个字符到Map中找 看返回值
null : 集合中没有这个字符 那么把这个字符以及次数1存入集合
非null : 集合中有这个字符 拿到它的值并 将值自增1 重新存入集合并覆盖原有值数据
总结 : 对于统计未知数量的东西,可以考虑使用map 扩展性好
二、HashMap嵌套HashMap案例
假设年代广告公司(era)两个部门 开发和生产 开发部门两个人 生产部门两个人 请使用嵌套(nest)完成它 并遍历出来
三、HashMap嵌套ArrayList案例
四、ArrayList嵌套HashMap案例
五、集合多层嵌套
例如 :
era公司
开发部门
人事组
员工对象1
员工对象2
美工组
员工对象3
员工对象4
生产部门
制作组
员工对象5
..
组装组
员工对象x
..
...
可以考虑map嵌套map再嵌套ArrayList等方法, 第一层map是公司 包含了各个部门 键是部门名称 值是部门集合
第二层是各个部门 包含了各个小组 键是小组名称 值是小组集合
第三层是各个小组 里面是各个小组的各个对象
面试题
1.HashMap和Hashtable的区别
这里要注意 一开始Hashtable就是这样命名的 虽然不规范但是就是这样和System类的arraycopy是一个道理
Hashtable此类实现一个哈希表,该哈希表将键映射到相应的值。
HashMap就是用来替代Hashtable的 就像ArrayList替代Vector一样
Hashtable和Vector在jdk1.2以后就被更先进的HashMap替代了,单其子类Properties依然活跃于历史舞台,Properties集合是唯一一个与IO流相结合的集合
区别 :
Hashtable 线程安全,效率低。并不允许null键和null值
HashMap 线程不安全,效率高。允许null键和null值 当然null键也只能有一个,注意一点HashMap一开始是没有null的
2.List,Set,Map是否都继承自Collection接口
List和Set继承于Collection接口 Map本身就是一个顶层接口
3.常见的集合类有哪些?都有哪些方法?
Collection
List
ArrayList类
Vector类
LinkedList类
Set
HashSet类
LinkedHashSet类
TreeSet类
Map
HashMap类
LinkedHashMap类
Hashtable类
TreeMap类