• Java集合框架(三)


       Map

       Map集合:该集合存储键值对,一对一对的往里存,而且要保证键的唯一性。

       Map

      |------HashTable:底层是哈希表数据结构,不可以存入null键null值。该集合是线程同步的。JDK1.0,效率低。

      |------HashMap:底层是哈希表数据结构,允许使用 null值和 null键,该集合是不同步的。JDK1.2,效率高。

      |------TreeMap:底层是二叉树数据结构,线程不同步,可以给map集合中的键进行排序。

       和Set很像,其实,Set底层就是使用了Map集合。

       方法总结:

      1、添加

        put(K key, V value)

        putAll(Map<? extends K,? extends V> m)

      2、删除

        clear()

        remove(Object key) 

      3、判断

        containsKey(Object key) 

        containsValue(Object value)

        isEmpty()

      4、获取

        get(Object key) 

        size()

        values()  

        entrySet() 

        keySet() 

       示例代码如下:

    import java.util.Collection;
    import java.util.HashMap;
    import java.util.Map;
    
    public class MapDemo {
    
        public static void main(String[] args) {
            Map<String, String> map = new HashMap<String, String>();
            
            //添加元素
            //添加元素,如果出现添加时,相同的键,那么后添加的值会覆盖原有的键对应的值,并put()方法返回被覆盖的值。
            System.out.println("put:" + map.put("01", "zhangsan01"));//输出null
            System.out.println("put:" + map.put("01", "wangwu"));
            map.put("02", "zhangsan02");
            map.put("03", "zhangsan03");
            
            //System.out.println("containsKey:" + map.containsKey("022"));
            //System.out.println("remove:" + map.remove("02")) ;
            
            //可以通过get()方法的返回值来判断一个键是否存在,通过返回null来判断
            System.out.println("get:" + map.get("023"));
            
            map.put(null, "haha");//HashMap允许使用 null值和 null键
            map.put("04", null);
            
            System.out.println("get:" + map.get("04"));
            System.out.println("get:" + map.get(null));
            
            
            //获取集合中所有的值
            Collection<String> coll = map.values();
            System.out.println(coll);
            System.out.println(map);
            
         }
    
    }

       Map集合的两种取出方式

       Map集合的两种取出方式:

      1、Set<K> keySet():将map所有的键存入到Set集合,因为Set集合具备迭代器,所以可以迭代方式取出所有的键,在根据get()方法,获取每一个键对应的值。

      Map集合的取出原理:将map集合转成set集合,在通过迭代器取出。

      2、Set<Map.Entry<K,V>> entrySet():将map集合中的映射关系存入到了set集合中,而这个关系的数据类型就是:Map.Entry。

      Map.Entry,其实Entry也是一个接口,它是Map接口中的一个内部接口。代码如下:

    interface Map {
        public static interface Entry {
            public abstract Object getKey();
            public abstract Object getValue();
        }
    }
    
    class HashMap implements Map {
        
        class Haha implements Map.Entry {
            public Object getKey() {
                
            }
            public Object getValue() {
                
            }
        }
        
    }

       示例代码:

    import java.util.HashMap;
    import java.util.Iterator;
    import java.util.Map;
    import java.util.Set;
    
    public class MapDemo1 {
    
        public static void main(String[] args) {
            Map<String, String> map = new HashMap<String, String>();
            
            map.put("01", "zhangsan01");
            map.put("02", "zhangsan02");
            map.put("03", "zhangsan03");
            map.put("04", "zhangsan04");
            
            
            //将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集合的所有的键的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);
            }
            */
            
        }
    
    }

       练习1:每一个学生都有对应的归属地。学生Student,地址String。学生属性:姓名,年龄。注意:姓名和年龄相同的视为同一个学生。保证学生的唯一性。

       分析:

    1. 描述学生。
    2. 定义Map容器,将学生作为键,地址作为值。存入。
    3. 获取map集合中的元素。

       代码如下所示:

    import java.util.HashMap;
    import java.util.Iterator;
    import java.util.Map;
    import java.util.Set;
    
    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 void setName(String name) {
            this.name = name;
        }
    
        public int getAge() {
            return age;
        }
    
        public void setAge(int age) {
            this.age = age;
        }
        
        @Override
        public boolean equals(Object obj) {
            if(!(obj instanceof Student)) 
                throw new ClassCastException("类型不匹配");
            Student student = (Student) obj;
            return this.name.equals(student.name) &&
                    this.age == student.age;
        }
    
        @Override
        public int hashCode() {
            return name.hashCode() + age * 34;
        }
    
        public String toString() {
            return name + ":" + age;
        }
    
        @Override
        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 class MapTest {
    
        public static void main(String[] args) {
            HashMap<Student, String> map = new HashMap<Student, String>();
            
            map.put(new Student("lisi1", 21), "beijing");
            map.put(new Student("lisi1", 21), "tianjin");
            map.put(new Student("lisi2", 22), "shanghai");
            map.put(new Student("lisi3", 23), "wuhan");
            map.put(new Student("lisi4", 24), "nanjing");
            
            //第一种取出方式  keySet()
            Set<Student> keySet = map.keySet();
            
            Iterator<Student> it = keySet.iterator();
            while(it.hasNext()) {
                Student s = it.next();
                String address = map.get(s);
                System.out.println(s + "..." + address);
            }
            
            //第二种取出方式 entrySet()
            Set<Map.Entry<Student, String>> entrySet = map.entrySet();
            Iterator<Map.Entry<Student, String>> it1 = entrySet.iterator();
            while(it1.hasNext()) {
                Map.Entry<Student, String> me = it1.next();
                Student stu = me.getKey();
                String address = me.getValue();
                System.out.println(stu + "..." + address);
            }
            
        }
    
    }

       练习2:需求:对学生对象的姓名进行升序排序。

       分析:因为数据是以键值对的形式存在的。所以要使用可以排序的Map集合。TreeMap。

       代码:

    import java.util.Comparator;
    import java.util.Iterator;
    import java.util.Map;
    import java.util.Set;
    import java.util.TreeMap;
    
    class Student1 implements Comparable<Student1> {
        private String name;
        private int age;
        
        public Student1(String name, int age) {
            this.name = name;
            this.age = 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 boolean equals(Object obj) {
            if(!(obj instanceof Student1)) 
                throw new ClassCastException("类型不匹配");
            Student1 stu = (Student1) obj;
            return this.name.equals(stu.name) &&
                    this.age == stu.age;
        }
    
        @Override
        public int hashCode() {
            return name.hashCode() + age * 34;
        }
    
        public String toString() {
            return name + ":" + age;
        }
    
        @Override
        public int compareTo(Student1 s) {
            int num = new Integer(this.age).compareTo(new Integer(s.age));
            
            if(num == 0) 
                return this.name.compareTo(s.name);
            
            return num;
        }    
    }
    
    class StuNameComparator implements Comparator<Student1> {
    
        @Override
        public int compare(Student1 s1, Student1 s2) {
            int num = s1.getName().compareTo(s2.getName());
            
            if(num == 0) 
                return new Integer(s1.getAge()).compareTo(new Integer(s2.getAge()));
            
            return num;
        }
        
    }
    public class MapTest1 {
    
        public static void main(String[] args) {
            Map<Student1, String> tm = new TreeMap<Student1, String>(new StuNameComparator());
            
            tm.put(new Student1("blisi3", 23), "wuhan");
            tm.put(new Student1("lisi1", 21), "beijing");
            tm.put(new Student1("alisi4", 24), "nanjing");
            tm.put(new Student1("lisi1", 21), "tianjin");
            tm.put(new Student1("lisi2", 22), "shanghai");
            
            //System.out.println(tm);
            
            Set<Map.Entry<Student1, String>> entrySet = tm.entrySet();
            
            Iterator<Map.Entry<Student1, String>> it = entrySet.iterator();
            while(it.hasNext()) {
                Map.Entry<Student1, String> me = it.next();
                Student1 stu = me.getKey();
                String addr = me.getValue();
                System.out.println(stu + ":::" + addr);
            }
            
        }
    
    }

       练习3:"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.Iterator;
    import java.util.Map;
    import java.util.Set;
    import java.util.TreeMap;
    
    public class MapTest2 {
    
        public static void main(String[] args) {
            String s = charCount("sdf+gz-x,cvasdf1xcvdfkk");
            System.out.println(s);
        }
        
        public static String charCount(String str) {
            char[] chs = str.toCharArray();
            
            TreeMap<Character, Integer> tm = new TreeMap<Character, Integer>();
            
            int count = 0;
            for(int i = 0; i < chs.length; i++) {
                if(!(chs[i] >= 'a' && chs[i] <= 'z' || chs[i] >= 'A' && chs[i] <= 'Z')) 
                    continue;//不是字母继续循环
                
                Integer value = tm.get(chs[i]);
                if(value != null) {
                    count = value;
                }
                count++;
                tm.put(chs[i], count);
                
                count = 0;
                
                /*
                if(value == null) {
                    tm.put(chs[i], 1);
                } else {
                    value = value + 1;
                    tm.put(chs[i], value);
                }
                */
                
            }
            
            //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();
            
        }
    
    }

       map集合扩展知识——一对多关系

       一对多的关系:一个学校有多个教室,每一个教室都有名称。一个教室有多个学生。

       示例代码:

    import java.util.ArrayList;
    import java.util.HashMap;
    import java.util.Iterator;
    import java.util.List;
    
    /*
    map集合扩展知识。
    
    map集合被使用是因为具备映射关系。
    
    "yureban" StudentM("01" "zhangsan")
    "yureban" StudentM("02" "lisi")
    
    "jiuyeban" "01" "wangwu"
    "jiuyeban" "02" "zhaoliu"
    
    一对多的关系
    一个学校有多个教室,每一个教室都有名称。
    一个教室有多个学生。
    
    */
    class StudentM {
        private String id;
        private String name;
        
        public StudentM(String id, String name) {
            this.id = id;
            this.name = name;
        }
    
        @Override
        public String toString() {
            return id + ":::" + name;
        }
        
        
    }
    public class MapDemo2 {
        
        public static void demo() {
            HashMap<String, List<StudentM>> czbk = new HashMap<String, List<StudentM>>();
            
            List<StudentM> yure = new ArrayList<StudentM>();
            List<StudentM> jiuye = new ArrayList<StudentM>();
            
            czbk.put("yureban", yure);
            czbk.put("jiuyeban", jiuye);
            
            yure.add(new StudentM("01", "zhangsan"));
            yure.add(new StudentM("04", "wangwu"));
            jiuye.add(new StudentM("01", "zhouqi"));
            jiuye.add(new StudentM("02", "zhaoliu"));
            
            Iterator<String> it = czbk.keySet().iterator();
            
            while(it.hasNext()) {
                String roomName = it.next();
                List<StudentM> room = czbk.get(roomName);
                System.out.println(roomName);
                getInfos(room);
            }
        }
        
        public static void getInfos(List<StudentM> list) {
            Iterator<StudentM> it = list.iterator();
            while(it.hasNext()) {
                StudentM s = it.next();
                System.out.println(s);
            }
        }
    
        public static void main(String[] args) {
            demo();
            
            /*
            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("jiuyeban", jiuye);
            
            yure.put("01", "zhangsan");
            yure.put("02", "lisi");
            
            jiuye.put("01", "zhaoliu");
            jiuye.put("02", "wangwu");
            
            //遍历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);
                getStudentMInfo(room);
            }
            
            //getStudentInfo(jiuye);
            */
        }
        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);
            }
        }
    }
    View Code
  • 相关阅读:
    ResGen.exe 生成resources文件方法 [转]
    C#【Winform】带参启动外部EXE
    SBO的5个开发原则机遇只给有准备的人[转]
    在SQL中插入临时表时使用自动增长的数据字段
    c# 强制退出
    C#实现SQL全库检索数据比较使用DataReader与DataAdapter+Datatable效率,差距惊人!
    推荐一个C#代码混淆器 .NET Reactor
    面向对象软件设计——设计模式学习
    AbstarctFactory模式——设计模式学习
    插入排序算法(直接,折半,希尔)
  • 原文地址:https://www.cnblogs.com/yerenyuan/p/5259349.html
Copyright © 2020-2023  润新知