Map接口详解

来源:互联网 发布:增值税发票软件 编辑:程序博客网 时间:2024/06/14 11:24
一、Map集合特点:存储的是键值对,键必须唯一

常用方法:

1、增
V put(K key, V value) 
          将指定的值与此映射中的指定键关联(可选操作)。
          当键相同时,用新值替换旧值,并返回原来的值
     void putAll(Map<? extends K,? extends V> m) 
          从指定映射中将所有映射关系复制到此映射中(可选操作)。 
2、删
void clear() 
          从此映射中移除所有映射关系(可选操作)。 
     V remove(Object key) 
          如果存在一个键的映射关系,则将其从此映射中移除(可选操作)。 
3、判断
boolean containsKey(Object key) 
          如果此映射包含指定键的映射关系,则返回 true。
     boolean equals(Object o) 
          比较指定的对象与此映射是否相等。
     boolean isEmpty() 
          如果此映射未包含键-值映射关系,则返回 true。   
4、获取
V get(Object key) 
          返回指定键所映射的值;如果此映射不包含该键的映射关系,则返回 null。
     int size() 
          返回此映射中的键-值映射关系数。 
     Collection<V> values() 
          返回此映射中包含的值的 Collection 视图。 
     重点:
     Set<Map.Entry<K,V>> entrySet() 
          返回此映射中包含的映射关系的 Set 视图。 
     Set<K> keySet() 
          返回此映射中包含的键的 Set 视图。 

二、体系结构

Map
|--Hashtable:底层是哈希表,必须实现 hashCode 方法和 equals 方法。jdk1.0 效率低
不能存储null值和键,线程同步
|--HashMap:底层是哈希表,允许使用 null 值和 null 键。不同步jdk1.2 效率高
|--TreeMap :底层是二叉树,线程不同步,键排序
和set很像,其他set底层就是使用了Map集合

三、元素存取

import java.util.*;/*Map实例*/class MapTest {public static void main(String[] args) {HashMap<String, String> h = new HashMap<String, String>();//添加数据h.put("01","lisi1");h.put("03","lisi3");h.put("04","lisi2");//获取out(h.get("03"));}//输出public static void out(Object obj) {System.out.println(obj);} }

四、Map集合和取出方式

Map集合取出原理:将Map集合转成Set集合,通过迭代器。在调用put()1、keySet();将Map中所有的键存入Set集合,在根据get方法获取每一个键对应的值import java.util.*;/*Map实例用keySet()取出所有的键和值*/class MapTest1 {public static void main(String[] args) {HashMap<String, String> h = new HashMap<String, String>();//添加数据h.put("01","lisi1");h.put("03","lisi3");h.put("04","lisi2");//生产set集合Set<String> set = h.keySet();//迭代器Iterator<String> it = set.iterator();//遍历元素while(it.hasNext()) {String key = it.next();String value = h.get(key);out("key->" + key + " value->" + value);}}//输出public static void out(Object obj) {System.out.println(obj);} }2、用entrySet()取元素import java.util.*;/*Map实例用entrySet()取出所有的键和值*/class MapTest2 {public static void main(String[] args) {HashMap<String, String> h = new HashMap<String, String>();//添加数据h.put("01","lisi1");h.put("03","lisi3");h.put("04","lisi2");//生产set集合Set<Map.Entry<String, String>> set = h.entrySet();//迭代器Iterator<Map.Entry<String, String>> it = set.iterator();//遍历元素while(it.hasNext()) {Map.Entry<String, String> m = it.next();String key = m.getKey();String value = m.getValue();out(key + ":" + value);}}//输出public static void out(Object obj) {System.out.println(obj);} }Map.Entry:内部实现(1)在Map接口中定义了一个静态Entry接口interface Map {public static interface Entry {//一些方法}}(2)Map类实现细节class HashMap implements Map {class Ha implements Map.Entry {//复写方法}} 

五、综合实例

import java.util.*;/*综合练习:将学生对象存储到HashMap中的键,值为住址姓名和年龄相同视为同一人思路:1、描述学生实现Comparable接口,覆盖compareTo() //是对象具有自然顺序重写equals(),HashCode() //存储到hash结构的容器中和toSting()2、将学生存储到HashMap容器中3、分别用keySet()和entrySet()对元素遍历*///学生class Student implements Comparable<Student> {private String name;private int age;//构造方法public Student(String name, int age) {this.name = name;this.age = age;}public String getName() {return name;}public int getAge() {return age;}//复写equlaspublic boolean equlas(Object obj) {if (obj instanceof Student)throw new ClassCastException("对象类型错误!");Student s = (Student)obj;return this.name.equals(s.name) && this.age == s.age; }//复写hashCodepublic int hashCode() {return this.name.hashCode() + age * 7;}//复写compareTopublic int compareTo(Student s) {int num = this.name.compareTo(s.name); //先按照姓名排序,升序if (num == 0) { //如果姓名相同,按年龄,升序return new Integer(this.age).compareTo(new Integer(s.age));}return num;}//复写toStringpublic String toString() {return name + "..." + age;}}//main class HashMapTest {public static void main(String[] args) {//创建容器HashMap<Student, String> hs = new HashMap<Student, String>();//添加数据hs.put(new Student("lisi1",14), "四川");hs.put(new Student("lisi4",19), "深圳");hs.put(new Student("lisi3",29), "北京");hs.put(new Student("lisi5",11), "上海");//第一种方法keySet()取数据Set<Student> set = hs.keySet();//迭代器Iterator<Student> it = set.iterator();//循环取出数据while(it.hasNext()) {Student key = it.next();String addr = hs.get(key);out("name:" + key.getName() + " age:" + key.getAge() + " 地址:" + addr);}out("");//第二种方法entrySet()//获取键值映射的Set集合Set<Map.Entry<Student, String>> s1 = hs.entrySet();//迭代器Iterator<Map.Entry<Student, String>> iter = s1.iterator();//循环取元素while(iter.hasNext()) {Map.Entry<Student, String> mp = iter.next();Student stu = mp.getKey();String addrs = mp.getValue();out("name:" + stu.getName() + " age:" + stu.getAge() + " addr:" + addrs);}}//输出public static void out(Object obj) {System.out.println(obj);}}

六、综合实例改进

import java.util.*;/*实现对学生对象的排序用TreeSet容器(默认是姓名排序)现在要求用年龄升序注意:学生对象同上*///main class HashMapTest1 {public static void main(String[] args) {//创建容器TreeMap<Student, String> hs = new TreeMap<Student, String>(new StudentNameComparator());//添加数据hs.put(new Student("lisi1",14), "四川");hs.put(new Student("lisi4",19), "深圳");hs.put(new Student("lisi3",29), "北京");hs.put(new Student("lisi5",11), "上海");//获取键值映射的Set集合Set<Map.Entry<Student, String>> s1 = hs.entrySet();//迭代器Iterator<Map.Entry<Student, String>> iter = s1.iterator();//循环取元素while(iter.hasNext()) {Map.Entry<Student, String> mp = iter.next();Student stu = mp.getKey();String addrs = mp.getValue();out("name:" + stu.getName() + " age:" + stu.getAge() + " addr:" + addrs);}}//输出public static void out(Object obj) {System.out.println(obj);}}//学生比较器class StudentNameComparator implements Comparator<Student> {public int compare(Student s1, Student s2) {int num = new Integer(s1.getAge()).compareTo(new Integer(s2.getAge()));if (num == 0)return s1.getName().compareTo(s2.getName());return num;}}

七、实例2

什么时候使用map集合:当数据直接出现映射关系时import java.util.*;/*练习:统计字符串中字母出现的次数输出如;a(13)b(3)c(9)...思路:1、定义一个TreeMap,因为数据之间有映射关系,而且是自然排序2、将字符串转成数组toCharArray()3、遍历字符数组,取出一个字符,去TreeMap中查询get()如果返回值为null说明,该字符以前没有出现,就将该字母和1作为键值对存入。否则,将出来的值加1,该字母和该值存入4、定义字符串缓冲区,拼接字符串(StringBuilder)*/class TreeMapCount {public static void main(String[] args) {String str = "anglakjngdpang";out(countChar(str));}//输出方法public static void out(Object obj) {System.out.println(obj);}//统计字母出现次数方法public static String countChar(String str) {//将字符串转成数组char[] chs = str.toCharArray();TreeMap<Character, Integer> tm = new TreeMap<Character, Integer>();//遍历字符串Integer count = 0;for (int i=0;i<chs.length;i++) {/*Character ch = chs[i];Integer value = tm.get(ch);if (value == null) {tm.put(ch, 1);} else {value++;tm.put(ch, value);}*/Character ch = chs[i];Integer value = tm.get(ch);if (value != null) count = value;count++;tm.put(ch, count);count = 0;}//拼接字符串StringBuilder sb = new StringBuilder();//获取键值映射集合SetSet<Map.Entry<Character, Integer>> set = tm.entrySet();//迭代器Iterator<Map.Entry<Character, Integer>> it = set.iterator();//循环取值while(it.hasNext()) {Map.Entry<Character, Integer> me = it.next();Character c = me.getKey();Integer value = me.getValue();sb.append(c + "(" + value + ")");}return sb.toString();}}

八、Map扩展知识

import java.util.*;/*练习:需求:对如下数据进行存储有一个学校,一个学校有很多班级,一个班级有很多学生,每个学生信息,姓名,学号分析:1、多对多关系,一个学校有很多个班级,班级有名称2、一个班级有很多学生,每个学生属于一个班级步骤:1、描述学生2、定义一个学生HashMap3、定义多个班级,4、向每个班级中添加学生*///学生类class Student {private String id;private String name;public Student(String id, String name) {this.id = id;this.name = name;}public String toString() {return id + "..." + name;}}//mainclass StorageTest {public static void main(String[] args) {method2();}//第一种方式,不将学校封装成对象,就要用HashMap,因为,//学号和姓名要一一对应public static void method1() {//创建学校HashMap<String, HashMap<String, String>> school = new HashMap<String, HashMap<String, String>>();//创建班级HashMap<String, String> ruanjianban = new HashMap<String, String>();HashMap<String, String> yishuban = new HashMap<String, String>();HashMap<String, String> dongmanban = new HashMap<String, String>();//将班级与学校关联school.put("软件班", ruanjianban);school.put("艺术班", yishuban);school.put("动漫班", dongmanban);//向每个班级添加学生ruanjianban.put("01", "zhangsan");ruanjianban.put("02", "lisi");ruanjianban.put("04", "wanger");yishuban.put("02", "zhangsan1");yishuban.put("01", "zhaoliu");dongmanban.put("05", "wangsan");//打印这个学校的学生信息outInfo(school);}//打印学生信息public static void outInfo(HashMap<String, HashMap<String, String>> s) { //传一个学校//先循环出班级的名称Iterator<String> it = s.keySet().iterator();while (it.hasNext()) {String room = it.next();out(room);//在由班级名称查找对于的学生HashMap<String, String> mm = s.get(room); //班级对象Iterator<String> it1 = mm.keySet().iterator();while(it1.hasNext()) {String key = it1.next();String value = mm.get(key);out(key + "..." + value);}}}//第二种方式,将学生封装成对象,那些第二个集合用Set就可以了public static void method2() {//创建学校HashMap<String, List<Student>> school = new HashMap<String, List<Student>>();//创建班级List<Student> ruanjianban = new ArrayList<Student>();List<Student> yishuban = new ArrayList<Student>();List<Student> dongmanban = new ArrayList<Student>();//将班级与学校关联school.put("软件班", ruanjianban);school.put("艺术班", yishuban);school.put("动漫班", dongmanban);//向每个班级添加学生ruanjianban.add(new Student("01", "zhangsan"));ruanjianban.add(new Student("02", "lisi"));ruanjianban.add(new Student("04", "wanger"));yishuban.add(new Student("02", "zhangsan1"));yishuban.add(new Student("01", "zhaoliu"));dongmanban.add(new Student("05", "wangsan"));//打印这个学校的学生信息outInfo1(school);}public static void outInfo1(HashMap<String, List<Student>> h) {//变量出班级名称Iterator<String> it = h.keySet().iterator();while(it.hasNext()) {String key = it.next();out(key);Iterator it2 = h.get(key).iterator();while(it2.hasNext()) {out(it2.next());}}}//输出public static void out(Object obj) {System.out.println(obj);}}