集合Map:
该集合存储键值对,一对一对往里存,而且要保证键的唯一性。
1.添加
put(Kkey, V value)
putAll(Map<?extends K,? extends V> m)
2.删除
clear()
remove(Object key)
3.判断
containsValue(Object value)
containsKey(Object key)
isEmpty()
4.获取
get(Objectkey)
size()
values()
entrySet() 返回此映射中包含的映射关系的 Set 视图。
keySet() 返回此映射中包含的键的 Set 视图。
Map
|--Hashtable: 底层是哈希表数据结构,不可以存入null键或null值。该集合是线程同步的。JDK 1.0.
|--HashMap:底层是哈希表数据结构,允许存入null键和null值。该集合是不同的。JDK 1.2.效率高。
|--TreeMap:底层是二叉树数据结构,线程不同步,可以用于给map集合中的键进行排序。
和Set很像。其实Set底层就是使用了Map集合。
import java.util.*; class day16 { public static void main(String[] args) { Map<String, String> map = new HashMap<String, String>(); //添加元素,如果出现添加时,出现相同的键,那么后添加的会覆盖原有的 //键的值,put方法会返回被覆盖的值 map.put("01", "zhangsan1");//put会返回该键原来的值 map.put("02", "zhangsan2"); map.put("03", "zhangsan3"); System.out.println(map.containsKey("02"));//输出true System.out.println(map.remove("02"));//输出zhangsan2 System.out.println(map);//输出{01=zhangsan1, 03=zhangsan3} System.out.println(map.get("023"));//输出null System.out.println(map.get("03"));//输出zhangsan3 //map.put("haha", null);//可以这样写 //获取map集合中所有的值 map.values(); Collection<String>coll = map.values(); System.out.println(coll);//输出[zhangsan1, zhangsan3] System.out.println(map);//输出{01=zhangsan1, 03=zhangsan3} } }
Map集合(不是一个元素,而是所有元素)的两种取出方式
1. Set<K> keySet(): 将map中所有的键存入到Set集合中。因为Set具备迭代器。所以可以用迭代方式取出所有的键,再根据get方法,获取每一个键对应的值。
取出原理:将map集合转成set集合,然后用迭代器取出。
2. Set<Map.Entry<k, v>>entrySet() : 将map集合中的映射关系存入到了set集合中,返回的类型为Map.Entry
第一种方式代码:
import java.util.*; class day16 { public static void main(String[] args) { Map<String, String> map = new HashMap<String, String>(); map.put("01", "zhangsan1"); map.put("03", "zhangsan3"); map.put("02", "zhangsan2"); map.put("04", "zhangsan4"); //先获取map集合的所有键的Set集合,keySet(); 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); } } }
第二种方式代码:
import java.util.*; class day16 { public static void main(String[] args) { Map<String, String> map = new HashMap<String, String>(); map.put("01", "zhangsan1"); map.put("03", "zhangsan3"); map.put("02", "zhangsan2"); 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+ " : " + value); } } }
Map.Entry其实Entry也是一个接口,它是Map接口中的一个内部接口
interface Map { public static interface Entry { public abstract Object getKey(); public abstract Object getValue(); } } class HashMap implements Map { class Hahs implements Map.Entry { public Object getKey(){} public Object getValue(){} } }
需求:
每一个学生都有对应的归属地。学生Student, 地址 String.学生属性包括姓名和年龄。
注意:姓名和年龄相同的视为同一个学生。保证学生的唯一性。
1.描述学生
2.定义map容器,将学生作为键,地址作为值,存入。
3.获取map集合中的元素。
import java.util.*; class Student implements Comparable<Student> { private String name; private int age; Student(String name, int age) { this.name = name; this.age = age; } public int compareTo(Student s) { int num = new Integer(this.age).compareTo(new Integer(s.age)); if(num == 0) return this.name.compareTo(s.name); return num; } public int hashCode() { return name.hashCode() + age * 34; } public boolean equals(Object obj) { if(!(obj instanceof Student)) throw new ClassCastException("类型不匹配"); Student s = (Student)obj; return this.name.equals(s.name) && this.age == s.age; } public String getName() { return name; } public int getAge() { return age; } public String toString() { return name+":"+age; } } class day16 { public static void main(String[] args) { Map<Student, String> hm = new HashMap<Student, String>(); hm.put(new Student("lisi1", 21), "beijing"); 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 stu = it.next(); String addr = hm.get(stu); System.out.println(stu+"..."+addr); } //第二种取出方式entrySet Set<Map.Entry<Student, String>> entrySet = hm.entrySet(); Iterator<Map.Entry<Student, String>> itr = entrySet.iterator(); while(itr.hasNext()) { Map.Entry<Student, String> me = itr.next(); Student stu = me.getKey(); String addr = me.getValue(); System.out.println(stu+"...."+addr); } } }
需求:对学生对象的年龄进行升序排序
因为数据是以键值对形式存在的。
所以要使用可以排序的map集合 TreeMap
import java.util.*; class Student implements Comparable<Student> { private String name; private int age; Student(String name, int age) { this.name = name; this.age = age; } public int compareTo(Student s) { int num = new Integer(this.age).compareTo(new Integer(s.age)); if(num == 0) return this.name.compareTo(s.name); return num; } public int hashCode() { return name.hashCode() + age * 34; } public boolean equals(Object obj) { if(!(obj instanceof Student)) throw new ClassCastException("类型不匹配"); Student s = (Student)obj; return this.name.equals(s.name) && this.age == s.age; } public String getName() { return name; } public int getAge() { return age; } public String toString() { return name+":"+age; } } class StuNameComparator implements Comparator<Student>//按照姓名排序 { public int compare(Student s1, Student s2) { int num = s1.getName().compareTo(s2.getName()); if(num == 0) return new Integer(s1.getAge()).compareTo(new Integer(s2.getAge())); return num; } } class day16 { public static void main(String[] args) { TreeMap<Student, String>tm = new TreeMap<Student, String>(); //如果想按照姓名排序,用比较器的形式 //TreeMap<Student, String>tm = new TreeMap<Student, String>(new StuNameComparator()); tm.put(new Student("lisi1", 22), "beijing"); tm.put(new Student("lisi1", 22), "beijing");//重复的,无效 tm.put(new Student("lisi2", 23), "shanghai"); tm.put(new Student("lisi3", 24), "nanjing"); tm.put(new Student("lisi4", 21), "wuhan"); Set<Map.Entry<Student, String>> entrySet = tm.entrySet(); Iterator<Map.Entry<Student, String>> it = entrySet.iterator(); while(it.hasNext()) { Map.Entry<Student, String> me = it.next(); Student stu = me.getKey(); String addr = me.getValue(); System.out.println(stu+"...."+addr); } } }
练习:
“sdfgzxcvasdfxcvdf”获取该字符串中的字母出现的个数
希望打印的结果:a(1)c(2)…..
通过结果发现,每一个字母都有对应的次数。说明字母和次数之间有映射关系。
注意了,当发现有映射关系时,可以选择map集合。因为map集合中存放的就是映射关系。
什么时候使用map集合呢?
当数据之间存在映射关系时,就要先想map集合。
思路:
1.将字符串转换成字符数组,因为要对每一个字母进行操作。
2.定义一个map集合,因为打印结果的字母有顺序,所以使用treemap集合。
3.遍历这个字符数组,将每个字母作为键去查map集合。如果返回null,就将该字母和1存入到map集合中,如果返回不是null,说明该字母在map集合已经存在并有对应次数。那么就获取该次数进行自增。然后将该字母和自增后的次数存入到map集合中,覆盖掉原来键所对应的值。
4.将map集合中的数据变成指定的字符串形式返回。
import java.util.*; class day16 { public static void main(String[] args) { System.out.println(charCount("aabfdddefff")); } public static String charCount(String str) { char[] chs = str.toCharArray(); TreeMap<Character, Integer> tm = new TreeMap<Character, Integer>(); int count = 0; for(int x = 0; x < chs.length; x ++) { Integer value = tm.get(chs[x]); if(value != null) count = value; count ++; tm.put(chs[x], count); count = 0; } //System.out.println(tm); StringBuilder sb = new StringBuilder(); Set<Map.Entry<Character, Integer>> entrySet = tm.entrySet(); Iterator<Map.Entry<Character, Integer>> it = entrySet.iterator(); while(it.hasNext()) { Map.Entry<Character, Integer> me = it.next(); Character ch = me.getKey(); Integer value = me.getValue(); sb.append(ch+"("+value+")"); } return sb.toString(); } }
输出:a(2)b(1)d(3)e(1)f(4)
map扩展知识:
map集合被使用是因为具备映射关系。
“yureban” “01” “zhangsan”
“yureban” “02” “lisi”
“jiuyeban” “01” “wangwu”
“jiuyeban” “02” “zhaowliu”
一个学校有多个教室,每个教室都有名称。
import java.util.*; class day16 { public static void main(String[] args) { HashMap<String, HashMap<String, String>>czbk = new HashMap<String, HashMap<String, String>>(); HashMap<String, String> yure = new HashMap<String, String>(); HashMap<String, String> jiuye = new HashMap<String, String>(); czbk.put("yureban", yure); czbk.put("jiuye", jiuye); yure.put("01", "zhangsan"); yure.put("02", "lisi"); jiuye.put("01", "wangwu"); jiuye.put("02", "zhaoliu"); //遍历czbk集合,获取所有的教室 Iterator<String> it = czbk.keySet().iterator(); while(it.hasNext()) { String roomName = it.next(); HashMap<String, String>room = czbk.get(roomName); System.out.println(roomName); getStudentInfo(room); } } public static void getStudentInfo(HashMap<String, String> roomMap) { Iterator<String> it = roomMap.keySet().iterator(); while(it.hasNext()) { String id = it.next(); String name = roomMap.get(id); System.out.println(id+" : "+name); } } }
“yureban” 封装为Student(“01” “zhangsan”)
“yureban” Stuent(“02” “lisi”)
“jiuyeban” Student(“01” “wangwu”)
“jiuyeban” Student(“02” “zhaowliu”)
import java.util.*; class Student { private String id; private String name; Student(String id, String name) { this.id =id; this.name = name; } public String toString() { return id+"..."+name; } } class day16 { public static void demo() { HashMap<String,List<Student>>czbk = new HashMap<String,List<Student>>(); List<Student> yure = new ArrayList<Student>(); List<Student> jiuye = new ArrayList<Student>(); czbk.put("yureban", yure); czbk.put("jiuyeban", jiuye); yure.add(new Student("01", "zhangsan")); yure.add(new Student("02", "zhangsan2")); jiuye.add(new Student("01", "zhangsan3")); jiuye.add(new Student("02", "zhangsan4")); Iterator<String> it = czbk.keySet().iterator(); while(it.hasNext()) { String roomName = it.next(); List<Student> room = czbk.get(roomName); System.out.println(roomName); getInfos(room); } } public static void getInfos(List<Student> list) { Iterator<Student> it = list.iterator(); while(it.hasNext()) { Student s = it.next(); System.out.println(s); } } public static void main(String[] args) { demo(); } }
输出:
jiuyeban
01...zhangsan3
02...zhangsan4
yureban
01...zhangsan
02...zhangsan2