Map集合:该集合存储键值对。一对一对往里存,而且要保证键的唯一性。每个键最多只能映射到一个值。
1.添加
put(K key,V value)
putAll(Map<? extends K,? extends V> m)
2.删除
clear()
remove(Object key)
3.判断
containsValue(Object value)
containsKey(Object key)
isEmpty
4.获取
get(Object key)
size()
values()
entrySet()
keySet()
Map
--HashTable:底层是哈希表数据结构,不可以存入null键null值。该集合是线程同步的。效率低
--HashMap:底层是哈希表数据结构,允许使用null键null值。该集合是不同步的。效率高
--TreeMap:底层是二叉树数据结构。线程不同步。可以用于给map集合中的键进行排序。
和Set很像,Set底层就是使用了Map集合。
public class Map_01 { public static void main(String[] args) { // TODO Auto-generated method stub Map<String,String> map=new HashMap<String,String>(); //添加元素,如果出现相同的键,那么后添加的值会覆盖原有键的对应值。打印时put方法返回原有键的值。 System.out.println("put:"+map.put("01", "zhangsan1")); System.out.println("put:"+map.put("01", "zhangsan11")); map.put("02", "zhangsan2"); map.put("03", "zhangsan3"); map.put("04","lisi"); System.out.println("containsKey:"+map.containsKey("01")); System.out.println("remove:"+map.remove("022")); //键不存在返回null,存在返回键对应的值 System.out.println("get:"+map.get("022"));////键不存在返回null,存在返回键对应的值 map.put(null,"zhangsan4"); System.out.println("getnull:"+map.get(null));//可以通过get方法的返回值来判断一个键是否存在,通过返回Null来判断 map.put("05", null); System.out.println("get04:"+map.get("05")); System.out.println(map); //键值对 //获取Map集合中所有的值 Collection<String> coll=map.values(); //值 System.out.println("mapvalue:"+coll); } }
Map集合的两种取出方式:
1.Set<key> keySet:将Map中所有键存入到Set集合。因为Set集合具备迭代器,所以可以通过迭代方式取出所有的键,根据get方法,获取每一个键对应的值。
Map集合的取出原理:将map集合转成set集合,再通过迭代器取出。
2.Set<Map.Entry<k,v>> entrySet:将Map集合中的映射关系存入早set集合中,而这个关系的数据类型就是:Map.Entry
entrySet
Map.Entry 其实Entry也是一个接口,它是Map接口 中的一个内部接口
public class Map_entrySet_02 { public static void main(String[] args) { // TODO Auto-generated method stub Map<String,String> map=new HashMap<String,String>(); map.put("02", "zhangsan2"); map.put("03", "zhangsan3"); map.put("01", "zhangsan1"); map.put("04", "zhangsan4"); //将Map集合中的映射关系取出。存入到Set集合中 Set<Map.Entry<String,String>> entrySet =map.entrySet(); Iterator<Map.Entry<String,String>> it=entrySet.iterator(); while(it.hasNext()){ Map.Entry<String,String> me=it.next(); String key=me.getKey(); String value=me.getValue(); System.out.println("key:"+key+",value:"+value); } } }
keySet
public class Map_keySet_03 { public static void main(String[] args) { // TODO Auto-generated method stub Map<String,String> map=new HashMap<String,String>(); map.put("02", "zhangsan2"); map.put("03", "zhangsan3"); map.put("01", "zhangsan1"); map.put("04", "zhangsan4"); //先获取Map集合中所有键的Set集合 Set<String> keySet=map.keySet(); //有了Set集合,就可以获取迭代器 Iterator<String> it=keySet.iterator(); while(it.hasNext()){ String key=it.next(); //有了键,就可以通过Map集合的get方法获取其对应的值 String value=map.get(key); System.out.println("key:"+key+",value="+value); } } }
练习:
每个学生都有对应的归属地。学生Student,地址String。学生属性:姓名,年龄。
注意:姓名和年龄相同的视为同一学生,保证学生的唯一性。
1.描述学生
2.定义Map容器,将学生作为键,地址作为值,存入。
3.获取map集合中的元素
public class HashMap_04 { public static void main(String[] args) { // TODO Auto-generated method stub HashMap<Student,String> hm=new HashMap<Student,String>(); hm.put(new Student("lisi1",21),"beijing"); hm.put(new Student("lisi1",21),"tianjin"); //被视为同一个人 hm.put(new Student("lisi2",22),"shanghai"); hm.put(new Student("lisi3",23),"nanjing"); hm.put(new Student("lisi4",24),"wuhan"); //第一种取出方式:keySet() Set<Student> keySet=hm.keySet(); Iterator<Student> it=keySet.iterator(); while(it.hasNext()){ Student s=it.next(); String addr=hm.get(s); System.out.println(s+","+addr); } //第二种取出方式:entrySet() Set<Entry<Student, String>> entrySet=hm.entrySet(); Iterator<Entry<Student,String>> it1=entrySet.iterator(); while(it1.hasNext()){ Entry<Student,String> e=it1.next(); Student s=e.getKey(); String str=e.getValue(); System.out.println(s+"---"+str); } } } class Student implements Comparable<Student>{ private String name; private int age; public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } Student(String name,int age){ this.name=name; this.age=age; } public String toString(){ return name+":"+age; } public int hashCode(){ return name.hashCode()+age*34; } public boolean equals(Object obj){ if(!(obj instanceof Student)){ throw new ClassCastException("传入的不是Student类"); } Student s=(Student) obj; return this.name.equals(s.name) && (this.age==s.age); } //学生对象可能存到二叉树里,按年龄排序 public int compareTo(Student o) { System.out.println("compareTo~~~~~~~~~~~~"); int num=new Integer(this.age).compareTo(new Integer(o.age)); if(num ==0){ return this.name.compareTo(o.name); } return num; } }
需求:对工人对象的年龄进行升序排列
因为数据是以键值对的形式存在的。所以要使用可以排序的Map集合。TreeMap
之后要求按姓名排序。工人类不能随意更改,指定一个比较器
public class TreeMap_05 { public static void main(String[] args) { // TODO Auto-generated method stub //TreeMap<Worker,String> hm=new TreeMap<Worker,String>(); //自定义排序 TreeMap<Worker,String> hm=new TreeMap<Worker,String>(new Com()); hm.put(new Worker("lisi1",27),"beijing"); hm.put(new Worker("lisi1",21),"tianjin"); //被视为同一个人 hm.put(new Worker("lisi2",25),"shanghai"); hm.put(new Worker("lisi3",23),"nanjing"); hm.put(new Worker("lisi4",24),"wuhan"); Set<Entry<Worker,String>> entrySet=hm.entrySet(); Iterator<Entry<Worker,String>> it=entrySet.iterator(); while(it.hasNext()){ Entry<Worker,String> e=it.next(); Worker w=e.getKey(); String s=e.getValue(); System.out.println(w+":"+s); } } } class Worker implements Comparable<Worker>{ private String name; private int age; public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } Worker(String name,int age){ this.name=name; this.age=age; } public String toString(){ return name+":"+age; } public int hashCode(){ return name.hashCode()+age*34; } public boolean equals(Object obj){ if(!(obj instanceof Student)){ throw new ClassCastException("传入的不是Worker类"); } Worker s=(Worker) obj; return this.name.equals(s.name) && (this.age==s.age); } public int compareTo(Worker o) { int num=new Integer(this.age).compareTo(new Integer(o.age)); if(num ==0){ return this.name.compareTo(o.name); } return num; } } class Com implements Comparator{ @Override public int compare(Object o1, Object o2) { // TODO Auto-generated method stub Worker w1=(Worker) o1; Worker w2=(Worker) o2; int num=w1.getName().compareTo(w2.getName()); if(num==0){ return new Integer(w1.getAge()).compareTo(w2.getAge()); } return num; } }
练习:
"sdfgzxcvasdfxcvdf"获取该字符串中字母出现的次数。
希望打印结果a(1)c(2)
通过结果发现每个字母都有对应的次数。说明字母和次数之间有映射关系
注意:
当发现有映射关系时,可以选择map集合。因为map集合中存放的就是映射关系。
什么时候使用map集合呢?
当数据之间存在着映射关系时,就要先想到map集合
思路:
1.将字符串转换成字符数组,因为要对每一个字母进行操作。
2.定义一个map集合,因为打印结果的字母有顺序,所以使用treemap集合
3.遍历字符数组
将每一个字母作为键去查map集合。如果返回null,将该字母和1存入到map集合中
如果返回不是null,说明该字母在map集合内已经存在,并有对应的次数,那么就获取该次数并进行自增。
然后将该字母和自增后的次数存入到map集合中,覆盖调用原来键所对应的值
4.将map集合中的数据变成指定的字符串形式返回。
public class TreeMap_06 { public static void main(String[] args) { // TODO Auto-generated method stub String s="sdf,gzxcv-asdfxc?vdf"; System.out.println(charCount(s)); } public static String charCount(String str){ //得到字符数组 char [] chs=str.toCharArray(); TreeMap<Character,Integer> tm=new TreeMap<Character,Integer>();//泛型中接收的都是引用数据类型,int char为基本数据类型 for(int x=0;x<chs.length;x++){ //不是字母 if(!(chs[x]>='a' && chs[x]<='z' || chs[x]>='A' && chs[x]<='Z')){ continue; } //集合中元素出现的次数 Integer value=tm.get(chs[x]); if(value == null){ tm.put(chs[x], 1); }else{ value=value+1; tm.put(chs[x],value); } } System.out.println(tm); //得到集合 StringBuffer bf=new StringBuffer(); Set<Entry<Character,Integer>> set=tm.entrySet(); Iterator<Entry<Character,Integer>> it=set.iterator(); while(it.hasNext()){ Entry<Character,Integer> e=it.next(); Character c=e.getKey(); Integer i=e.getValue(); //System.out.println(c+"("+i+")"); bf.append(c+"("+i+")"); } return bf.toString(); } }
map扩展知识
map集合被使用是因为具备映射关系。
"数学班" "01" "zhangsan"
"数学班" "02" "lisi"
"化学班" "01" "wangwu"
"化学班" "02" "zhaoliu"
一个学校有多个教室,每个教室多个学生
获取每个班的班级名称、学生Id及姓名
public class Map_07 { public static void main(String[] args) { /*HashMap<String,HashMap<String,String>> school=new HashMap<String,HashMap<String,String>>(); HashMap<String,String> math=new HashMap<String,String>(); HashMap<String,String> chemical=new HashMap<String,String>(); school.put("数学班", math); school.put("化学班", chemical); math.put("01", "zhangsan"); math.put("02", "lisi"); chemical.put("01", "wangwu"); chemical.put("02", "zhaoliu");*/ HashMap<String,HashMap<String,String>> school=new HashMap(); HashMap<String,String> math=new HashMap(); HashMap<String,String> chemical=new HashMap(); school.put("数学班", math); school.put("化学班",chemical); math.put("01", "张三"); math.put("02","李四"); chemical.put("01","王五"); chemical.put("02", "赵六"); //获取学校所有班的键 Set<String> cl=school.keySet(); Iterator<String> it=cl.iterator(); while(it.hasNext()){ String clKey=it.next(); //获取每个班级键 System.out.println(clKey+"--"); HashMap<String,String> room=school.get(clKey); //获取每个班级名称 //System.out.println(room); getStuInfo(room); } } //获取每个班学生及编号 public static void getStuInfo(HashMap<String,String> roomMap){ // HashMap hm,String room 告诉学校,教室 Set<String> room=roomMap.keySet(); Iterator<String> it=room.iterator(); while(it.hasNext()){ String id=it.next(); String name=roomMap.get(id); System.out.println("id:"+id+",name:"+name); } } }