Java 集合框架之 Map
-
Map 集合特点:
- Map 集合一次添加一对元素, Collection 一次添加一个元素
- Map 集合中存储的是键值对(类似夫妻), Map 集合必须保证键的唯一性
- Map 称为双列集合, Collection 称为单列集合
-
常用方法:
// 1. 添加
value put(key,value); // 返回前一个与 key 关联的值, 如果没有, 返回 null
// 2. 删除
void clear(); // 清空 Map() 集合
value remove(key); // 根据指定 key 删除这个键值对, 改变集合长度
// 3. 判断
boolean containsKey(key);
boolean containsValue(value);
boolean isEmpty();
// 4. 获取
int size(); // 获取键值对的个数
value get(key); // 通过键获取值, 如果没有该键,返回 null
- 取出 Map 集合中所有元素
// 第一种方式:
/*
1. 通过 keySet() 方法获取 Map 集合中所有的键所在的 Set 集合,
2. 通过 Set 的迭代器获取到每一个键
3. 对每一个键通过 Map 集合的 get(key) 方法获取对应的值
*/
public static void main(String[] args){
Map<Integer, String> map = new HashMap();
map.put(3,"wangcai");
map.put(7,"xiaoqiang");
map.put(9,"zhaoliu");
map.put(2,"lisi");
// 获取 Set 集合
Set<Integer> keySet = map.keySet();
Iterator<Integer> it = keySet.iterator();
while(it.hasNext()){
Integer key = it.next();
String value = map.get(key);
System.out.println(key+"..."+value);
}
}
// 第二种方式: 通过 entrySet() 方法
// 该方法将键和值的映射关系作为对象存储到了 Set 集合中,
// 而这个映射关系的类型就是 Map.Entry 类型(这个映射关系即结婚证)
public static void main(String[] args){
Map<Integer, String> map = new HashMap();
map.put(3,"wangcai");
map.put(7,"xiaoqiang");
map.put(9,"zhaoliu");
map.put(2,"lisi");
Set<Map.Entry<Integer, String>> entrySet = map.entrySet();
Iterator<Map.Entry<Integer, String>> it = entrySet.iterator();
while(it.hasNext()){
Map.Entry<Integer, String> me = it.next(); // Map.Entry<Integer, String> 表示类型
Integer key = me.getKey();
String value = me.getValue();
System.out.println(key+":::"+value);
}
}
// Map.Entry 备注: 内部类. 例如:
Outer.Inner.show();
class Outer{
static class Inner{
static void show();
}
}
// 备注二: 因为 Map 中键是唯一的, 所以使用 Set 集合存储所有的键.
3.1 特例: 仅获取 Map 集合中所有的值
public static void main(String[] args){
Map<Integer, String> map = new HashMap();
map.put(3,"wangcai");
map.put(7,"xiaoqiang");
map.put(9,"zhaoliu");
map.put(2,"lisi");
Collection<String> values = map.values();
Iterator<String> it = values.iterator();
while(it.hasNext()){
System.out.println(it.next());
}
}
//备注: 因为 Map 集合中键所对应的值并不一定是唯一的, 所以 values() 方法返回值类型为 Collection
-
Map 集合常见子类对象(请参照Set集合)
- Hashtable : 内部结构是哈希表,是同步的. 不允许 null 作为键, null 作为值
- Properties : 用来存储键值对型的配置信息, 可以和 IO 技术相结合
- HashMap : 内部结构是哈希表,不是同步的. 允许 null 作为键, null 作为值
- LinkedHashMap : 保证存入和取出的顺序一致
- TreeMap : 内部结构是二叉树,不是同步的, 可以对 Map 集合中的键进行排序
- Hashtable : 内部结构是哈希表,是同步的. 不允许 null 作为键, null 作为值
-
练习
// "fdgavcbsacdfs" 获取该字符串中, 每一个字母出现的次数
// 要求打印结果是: a(2)b(1)....;
/*
思路:
对结果的分析发现,字母和次数之间存在着映射关系, 而且这种关系很多
很多就需要存储, 能存储映射关系的容器有数组和 Map 集合
关系的中的一方是有序编号吗? 不是!
那就使用 Map 集合. 又发现可以保证唯一性的一方具备着顺序如, a, b, c...
所以使用 TreeMap 集合
这个集合最终应该存储的是字母和次数的对应关系
步骤:
1. 因为操作的是字符串中的字母, 所以先将字符串变成字符数组
2. 遍历字符数组,用每一个字母作为键去 Map 集合中查询,
如果该字母键不存在, 就将该字母作为键作为值存储到 Map 集合中
如果该字母键存在, 就将该字母键对应的值取出并 +1, 再将该字母和 +1 后的值存储到 Map 集合中
键相同,值会覆盖. 这样就记录住了该字母出现的次数
3. 遍历结束, Map 集合就记录了所有字母出现的次数
*/
public class MapTest {
public static void main(String[] args){
String str = "fdgavc +++ ==== $ %# bsacdfs";
String s = getCharCount(str);
System.out.println(s);
}
public static String getCharCount(String str){
// 将字符串变成字符数组
char[] chs = str.toCharArray();
// 定义 Map 集合表
Map<Charater, Integer> map = new TreeMap<Charater, Integer>();
for(int i = 0; i<chs.length; i++){
// 将非字母的字符去掉
if(!(chs[i] >= 'a' && chs[i] <= 'z' || chs[i] >= 'A' && chs[i] <= 'Z'))
continue;
// 将数组中的字母作为键去查 Map 表
Integer value = map.get(chs[i]);
// 判断值是否为 null
// 第一种方式:
if(value == null){
map.put(chs[i], 1);
} else {
map.put(chs[i], value+1);
}
// 第二种方式
int count = 0; // 计数器
if(value != null){
count = value;
}
count++;
map.put(chs[i], count);
}
return mapToString(map);
}
private static String mapToString(Map<Charater, Integer> map) {
// 使用 StringBuilder 存储字符串
StringBuilder sb = new StringBuilder();
Iterator<Charater> it = map.keySet().iterator();
while(it.hasNext()){
Charater key = it.next();
Integer value = map.get(key);
sb.append(key+"("+value+")");
}
return sb.toString();
}
}
参考资料