从屌丝到架构师的飞越(集合篇)-Map
一.介绍
Map 是一种把键对象和值对象进行关联的容器,而一个值对象又可以是一个Map,依次类推,这样就可形成一个多级映射。对于键对象来说,像Set一样,一个 Map容器中的键对象不允许重复,这是为了保持查找结果的一致性;
如果有两个键对象一样,那你想得到那个键对象所对应的值对象时就有问题了,可能你得到的并不是你想的那个值对象,结果会造成混乱,所以键的唯一性很重要,也是符合集合的性质的。
当然在使用过程中,某个键所对应的值对象可能会发生变化,这时会按照最后一次修改的值对象与键对应。对于值对象则没有唯一性的要求,你可以将任意多个键都映射到一个值对象上,这不会发生任何问题(不过对你的使用却可能会造成不便,你不知道你得到的到底是那一个键所对应的值对象)。
二.知识点介绍
1、HashMap
2、TreeMap
三.上课对应视频的说明文档
1、HashMap
HashMap也用到了哈希码的算法,以便快速查找一个键,它根据键的hashCode值存储数据,大多数情况下可以直接定位到它的值,因而具有很快的访问速度,但遍历顺序却是不确定的。 HashMap最多只允许一条记录的键为null,允许多条记录的值为null。HashMap非线程安全,即任一时刻可以有多个线程同时写HashMap,可能会导致数据的不一致。
案例:
public class MapTest {
public static void main(String[] args) {
// Map不同于List,它的key不一定是数字
Map map = new HashMap();
map.put("疯狂Java讲义",109);
map.put("疯狂iOS讲义",10);
map.put("疯狂Ajax讲义",79);
// 如果新的value覆盖了原有的value,该方法返回被覆盖的value
System.out.println(map.put("疯狂iOS讲义",99)); // 输出10
System.out.println(map);
// 判断是否包含指定key
System.out.println("是否包含值为疯狂iOS讲义key:"+map.containsKey("疯狂iOS讲义"));
System.out.println("是否包含值为99 value:"+map.containsValue(99));
// 遍历map
for (Object key : map.keySet()) {
System.out.println(key+"-->"+map.get(key));
}
}
}
(1) 根据键查询值
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
/*
* Map集合的遍历,根据键查询值
*
* 思路:
* A:获取所有的键
* B:遍历键的集合,获取得到每一个键
* C:根据键查询值
* */
public class IntegerDemo {
public static void main(String[] args) {
// TODO Auto-generated method stub
Map<String, String> map = new HashMap<String, String>();
map.put("hello", "world");
map.put("java", "c++");
map.put("sql", "os");
System.out.println(map);
// A:获取所有的键
Set<String> set = map.keySet();
// B:遍历键的集合,获取得到每一个键
for (String key : set) {
// C:根据键查询值
String value = map.get(key);
System.out.println(key + "---" + value);
}
}
}
(2) 根据键值对的对象查询键和值
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
/*
* Map集合的遍历,根据对象查询键和值
*
* 思路:
* A:获取所有的键值对对象的集合
* B:遍历键值对对象的集合,得到每一个键值对的对象
* C:获取键和值
* */
public class IntegerDemo {
public static void main(String[] args) {
// TODO Auto-generated method stub
Map<String, String> map = new HashMap<String, String>();
map.put("hello", "world");
map.put("java", "c++");
map.put("sql", "os");
System.out.println(map);
// A:获取所有的键值对对象的集合
Set<Map.Entry<String, String>> set = map.entrySet();
// B:遍历键值对对象的集合,得到每一个键值对的对象
for (Map.Entry<String, String> me : set) {
// C:获取键和值
String key = me.getKey();
String value = me.getValue();
System.out.println(key + "---" + value);
}
}
}
2、TreeMap
TreeMap则是对键按序存放,因此它便有一些扩展的方法,比如firstKey(),lastKey()等,你还可以从TreeMap中指定一个范围以取得其子Map。
键和值的关联很简单,用put(Object key,Object value)方法即可将一个键与一个值对象相关联。用get(Object key)可得到与此key对象所对应的值对象。
案例:
public class TestTreeMap
{
public static void main(String[] args)
{
SortedMap<String,String> map=new TreeMap<String,String>();
//插入键值对
map.put("bkey","bvalue");
map.put("dkey","dvalue");
map.put("ckey","cvalue");
map.put("akey","avalue");
//获取键值Set
Set<String> keySet=map.keySet();
//将键值Set转成数组
Object[] keyArray=keySet.toArray();
//按照键值依序获取值对象
for(int i=0; i<keyArray.length; i++)
System.out.println( "key="+(String)keyArray[i]+"; value="+map.get((String)keyArray[i]) );
}
}
案例:"aababcabcdabcde",获取字符串中每一个字母出现的次数要求结果:a(5)b(4)c(3)d(2)e(1)
import java.util.Scanner;
import java.util.Set;
import java.util.TreeMap;
/** 分析:
* A:定义一个字符串(可以改进为键盘录入)
* B:定义一个TreeMap集合
* 键:Character
* 值:Integer
* C:把字符串转换为字符数组
* D:遍历字符数组,得到每一个字符
* E:拿刚才得到的字符作为键到集合中去找值,看返回值
* 是null:说明该键不存在,就把该字符作为键,1作为值存储
* 不是null:说明该键存在,就把值加1,然后重写存储该键和值
* F:定义字符串缓冲区变量
* G:遍历集合,得到键和值,进行按照要求拼接
* H:把字符串缓冲区转换为字符串输出
*/
public class TreeMapDemo {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
System.out.println("请输入一个字符串:");
String line = sc.nextLine();
// 定义一个TreeMap集合
// Character 和Char的区别,基本类型和引用类型
TreeMap<Character, Integer> tm = new TreeMap<Character, Integer>();
//把字符串转换为字符数组
char[] chs = line.toCharArray();
for(char ch : chs){
//拿刚才得到的字符作为键到集合中去找值,看返回值
Integer i = tm.get(ch);
//是null:说明该键不存在,就把该字符作为键,1作为值存储
if(i == null){
tm.put(ch, 1); // 放入map集合中
}else {
// 不是null:说明该键存在,就把值加1,然后重写存储该键和值
i++;
tm.put(ch,i);
}
}
// 字符串的遍历和拼接
StringBuilder sb= new StringBuilder();
//遍历集合,得到键和值
Set<Character> set = tm.keySet();
for(Character key : set){
Integer value = tm.get(key);
sb.append(key).append("(").append(value).append(")");
}
String result = sb.toString();
System.out.println("result:"+result);
}
}