Map集合
* 1.Map集合中存储的是一对儿元素。键和值。之间存在着对应关系。
* 2.必须要保证键的唯一性。
* 3.如果存储键相同,值会覆盖。
特点:
1,存储的都是键值对。
2,要保证键的唯一性。
存的方式:put(key,value);
取的方式:keySet(),entrySet(),values();
原理:就是将map集合转成set集合或者Collection集合,再通过Iterator取出。
Map
|--Hashtable:哈希表结构,同步的。null不可以作为键和值。
|--HashMap:哈希表结构,不同步的。替代了Hashtable。允许null作为键和值。
|--TreeMap:二叉树结构,不同步的,可以对map集合中的键进行排序。排序需要比较大小。
排序方式有两种:1.元素自身具有比较性
2.容器构造器中传入一个比较器
集合框架-Map-常见方法
put(K key, V value)
将指定的值与此映射中的指定键关联(可选操作)。
返回:
返回与 key 相关联的先前值,如果 key 没有映射关系,则返回 null(返回 null 可能还表示映射以前将 null 与指定键关联)
get(Object key)
返回:
指定键所映射的值;如果此映射不包含该键的映射关系,则返回 null
@Test public void test1(){ /* * 需求:将学号和对应的学生姓名进行存储。 */ Map<Integer,String> map = new HashMap<Integer,String>(); //存储键值对。 System.out.println(map.put(2,"小花"));//之前与 key 关联的值,如果没有针对 key 的映射关系,则返回 null System.out.println(map.put(2,"麻子"));//小花,麻子之前是小花 map.put(6,"赵六"); map.put(1,"王五"); System.out.println(map);//并没有排序,并且不是有序。2=麻子,“小花”被覆盖 System.out.println(map.get(1));//王五 } 测试结果: null 小花 {1=王五, 2=麻子, 6=赵六} 王五
集合框架-Map-keySet方法
Set底层用的是Map集合的Key // * 获取Map中的所有键值对。 // * Map取出所有元素的原理:将map先转成set,再使用迭代器。 // * @Test public void test2(){ Map<String,String> map = new HashMap<String,String>(); map.put("zhangsan","北京"); map.put("lisi","上海"); map.put("wangwu","成都"); map.put("zhaoliu","广州"); System.out.println(map); //第一种方式: //获取map集合中的键的集合。keySet(); Set<String> keySet = map.keySet(); //通过set集合获取迭代器。 Iterator<String> it = keySet.iterator(); while(it.hasNext()){ String key = it.next(); String value = map.get(key); System.out.println(key+":"+value); } }
集合框架-Map-entrySet方法&values方法
@Test public void test3(){ Map<String,String> map = new HashMap<String,String>(); map.put("zhangsan","北京"); map.put("lisi","上海"); map.put("wangwu","成都"); map.put("zhaoliu","广州"); System.out.println(map); //第二种方式: //获取map集合中所有的键值关系集合。entrySet,键值关系的类型是 Map.Entry. 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); } }
@Test public void test4(){ Map<String,String> map = new HashMap<String,String>(); map.put("zhangsan","北京"); map.put("lisi","上海"); map.put("wangwu","成都"); map.put("zhaoliu","广州"); System.out.println(map); //第三种方式:获取值的集合。values(); Collection<String> values = map.values(); Iterator<String> it = values.iterator(); while(it.hasNext()){ String value = it.next(); System.out.println(value); } }
Map-HashMap存储自定义对象
package cn.itcast.p1.map; import java.util.HashMap; import java.util.Iterator; import java.util.LinkedHashMap; import cn.itcast.bean.Student; public class HashMapDemo { public static void main(String[] args) { /* * 将学生对象存储和学生的归属地存储到HashMap集合中。 * 对于学生对象,同姓名同年龄视为同一个人。 */ //1,创建一个HashMap集合对象。 HashMap<Student,String> hm = new HashMap<Student,String>(); //2,将学生对象和归属地存储到集合中。 hm.put(new Student("xiaoming",20),"北京"); hm.put(new Student("abc",20),"成都"); hm.put(new Student("wangcai",20),"广州"); hm.put(new Student("caige",20),"上海"); hm.put(new Student("wangcai",20),"铁岭"); //3,取出map集合中所有的元素。获取Map中键的集合,通过keySet方式。 //Set<Student> keySet = hm.keySet(); //Iterator<Student> it = keySet.iterator(); Iterator<Student> it = hm.keySet().iterator(); while(it.hasNext()){ Student key = it.next(); String value = hm.get(key); System.out.println(key.getName()+":"+key.getAge()+":"+value); } } }
//比较两个对象是否一样,重写hashcode方法 和 equals方法 package cn.itcast.bean; public class Student{ private String name; private int age; public Student() { super(); } public Student(String name, int age) { super(); this.name = name; this.age = age; } /** * 覆盖hashCode方法 * @return */ @Override public int hashCode() { final int NUMBER = 31;//对31这个数字进行命名定义。增强了阅读性。 return name.hashCode()+age*NUMBER; } /** * 覆盖equals方法 * @return */ @Override public boolean equals(Object obj) { if(!(obj instanceof Student)) throw new NotTypeException("错误的类型"); Student stu = (Student)obj; return this.name.equals(stu.name) && this.age == stu.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; } @Override public String toString() { return "Student [name=" + name + ", age=" + age + "]"; } }
Map-TreeMap存储自定义对象
package cn.itcast.p1.map; import java.util.Iterator; import java.util.Map; import java.util.Set; import java.util.TreeMap; import cn.itcast.bean.Student; import cn.itcast.p2.comparator.ComparatorByName; public class TreeMapDemo { public static void main(String[] args) { //1,创建TreeMap集合。 //设置比较器,定义排序方式:map的key的排序方式根据对象的name值的自然排序 TreeMap<Student,String> tm = new TreeMap<Student,String>( new Comparator<Student>(){ @Override public int compare(Student o1, Student o2) { int temp = o1.getName().compareTo(o2.getName()); return temp==0?o1.getAge()-o2.getAge(): temp; } } }); tm.put(new Student("xiaoming",26),"北京"); tm.put(new Student("abc",24),"成都"); tm.put(new Student("wangcai",21),"广州"); tm.put(new Student("caige",27),"上海"); tm.put(new Student("wangcai",21),"铁岭"); // 取出集合中的元素。获取Map集合中所以键值关系集合方法entrySet() //Set<Map.Entry<Student,String>> entrySet = tm.entrySet(); //Iterator<Map.Entry<Student,String>> it = entrySet.iterator(); Iterator<Map.Entry<Student,String>> it = tm.entrySet().iterator(); while(it.hasNext()){ Map.Entry<Student, String> me = it.next(); Student key = me.getKey(); String value = me.getValue(); System.out.println(key.getName()+"::"+key.getAge()+"::"+value); } } }
Map-什么时候用Map
* 什么时候用map集合?
* 在分析需求中,如果出现了映射关系,就要先想到具备对应关系的容器。
* 比如 数组,list,map。
* 如果对应关系的一方是有序的数字,可以考虑数组和list,元素固定考虑数组,不固定考虑list。
* 如果对象关系的一方没有有序的数字,就要想到map。
*
* 通常这些对应关系的容器都可以用于查表法。
package cn.itcast.test; import java.util.HashMap; import java.util.Map; public class Test { public static void main(String[] args) { String week = getCnWeek(3); String enweek = getEnWeek(week); System.out.println(week); System.out.println(enweek); } /** * 通过中文获取英文。 * @param num * @return 返回的是cnweek参数对应的英文表示方式。 * 如果没有对应返回 null。 */ public static String getEnWeek(String cnweek){ /* * 创建一个表。存储中英对应星期。 */ Map<String,String> weekMap = new HashMap<String,String>(); weekMap.put("星期一", "Monday"); weekMap.put("星期二", "Tuesday"); weekMap.put("星期三", "Wednesday"); weekMap.put("星期四", "Thursday"); weekMap.put("星期五", "Friday"); weekMap.put("星期六", "Saturday"); weekMap.put("星期日", "Sunday"); return weekMap.get(cnweek); } public static String getCnWeek(int num){ //定义一个表。 String[] weeks = {"","星期一","星期二","星期三","星期四","星期五","星期六","星期日"}; return weeks[num]; } }
Map-练习-字母次数
/*作业: * "ert+yuiodf8g.hjkt"想要知道每个字母出现的次数。 * a(3)b(5)c(1)e(6).....友情提示:当需求中有对应关系时,先要考虑map集合。 * * 思路: * 1,字母很多,必须要进行存储。存储就需要使用容器。 * 2,哪个容器呢?数组,不合适,长度不确定。StringBuffer,不合适,要对单个字母操作。 * Collection,好像也不太合适,存储了字母后,次数咋办? * 3,发现字母和次数之间存在着对应关系,所以可以使用map集合。 * 具体用哪个子类对象呢?发现要求的结果中abc等出现是有顺序的。所以可考虑使用TreeMap。 * 4,map集中,存储的就是字母和对应的次数,字母作为键。map作为表。 * 将字符串中的每一个字母都去查表。如果该字母没查找对应的次数,就将该字母和1存储到表中。 * 如果查到次数,将次数加+1后,将该字母和次数存储到表中。 * */ package cn.itcast.test; import java.util.Iterator; import java.util.Map; import java.util.TreeMap; public class Test2 { public static void main(String[] args) { String str = "erAt+yuAeioCrdCfe8g.hyjkt"; str = sortChar(str); System.out.println(str); } public static String sortChar(String str){ //1,定义一个存储字母和次数的表。TreeMap. Map<Character,Integer> map = new TreeMap<Character,Integer>(); //2,将字符串转成字符数组。 char[] chs = str.toCharArray(); //3,对数组进行遍历。 for(int x=0; x<chs.length; x++){ if(!isLetter(chs[x])){ continue;//不是字母,回去循环,下面的语句不要执行 } //将遍历到的字符作为键。去查表。获取对应的次数。 Integer value = map.get(chs[x]); int count = 0; if(value!=null){ count = value; } count++; //将字母和对应的次数存储到map集合中。 map.put(chs[x], count); } return mapToString(map); } /* * 将map集合转成指定格式的字符串。键(值)键(值).... */ private static String mapToString(Map<Character, Integer> map) { //元素很多,最终要变成字符串。废话吗?不用废话,StringBuilder正好ok。 StringBuilder sb = new StringBuilder(); //遍历map。 Iterator<Map.Entry<Character, Integer>> it = map.entrySet().iterator(); while(it.hasNext()){ Map.Entry<Character, Integer> me = it.next(); Character key = me.getKey(); Integer value = me.getValue(); //StringBuilder的增加字符串的方法append() sb.append(key+"("+value+")"); } return sb.toString(); } /* * 判断字符是否是字母。 */ private static boolean isLetter(char c) { return c>='a' && c<='z' || c>='A' && c<='Z'; } }