zoukankan      html  css  js  c++  java
  • 集合框架map_DAY18

    1:map集合(掌握)

        (1)Map集合存储的是键值对元素。键是唯一的,值可以重复。 

        (2)Map和Collection的区别?

                 A:Map是双列集合,存储的元素键值对,键唯一,值可以重复。

                 B:Collection是单列集合,存储的元素是单一的,List集合可以重复,Set集合元素唯一。

        (3)Map集合的功能

               A:添加功能

                       V put(K key,V value)

              B:删除功能

                 remove(K key)

              C:判断功能

                 containsKey(K key)

                 containsValue(V value)

              D:获取功能

                 V  get(K key)

                 Set<K>   keySet()

                 Collection<V>   values()

                 Set<Map.Entry<K,V>>   entrySet()      返回所有键值对对应关系

                       Map.Entry是Map内的一个内部接,包含的主要方法

                                K   getKey()

                                V   getValue()

                                   V    setValue(V value)  设置值

                E:长度功能

                 int   size()

        (4)Map集合的数据结构问题:

             Map集合的数据结构对键有效,跟值无关。

             它的底层数据结构和Set中讲解的一致。

                   如果是哈希表结构,就需要重写hashCode()和equals(),保证存储元素的唯一性。

                  如果是二叉树结构,就有两种方式:Comparable,Comparator,保证存储的元素的有序性。 例子程序如下:

    mport java.util.Comparator;
    import java.util.TreeMap;
    
    /*
     * 使用TreeMap存储<Person,String>
     */
    public class Demo7 {
    
        public static void main(String[] args) {
            //第一种方式:使键的类型实现Comparable接口,完成比较大小的逻辑
            TreeMap<Person, String> map = new TreeMap<>();
            Person p = new Person("唐嫣", 28);
            String s = "貂蝉";
            
            Person p2 = new Person("卢俊义",42);
            String s2 = "玉麒麟";
            
            Person p3 = new Person("2张顺",32);
            String s3 = "浪里白条";
            
            Person p4 = new Person("1花荣",32);
            String s4 = "小李广";
            
            map.put(p, s);
            map.put(p2, s2);
            map.put(p3, s3);
            map.put(p4, s4);
            
            System.out.println(map);
            
            //第二种方式:创建集合对象时给予对应的比较器Comparator
            TreeMap<Person, String> map2 = new TreeMap<>(new Comparator<Person>(){
    
                @Override
                public int compare(Person o1, Person o2) {
                    int result = o1.getName().compareTo(o2.getName());
                    if(result==0) {
                        result = o1.getAge()-o2.getAge();
                    }
                    return result;
                }});
            
            map2.put(p, s);
            map2.put(p2, s2);
            map2.put(p3, s3);
            map2.put(p4, s4);
            
            System.out.println(map2);
        }
    
    }
    View Code
    public class Person implements Comparable<Person>{
    
        private String name;
        private int age;
        public Person() {
            super();
            // TODO Auto-generated constructor stub
        }
        public Person(String name, int age) {
            super();
            this.name = name;
            this.age = age;
        }
        
        //先比较年龄,后比较姓名
        @Override
        public int compareTo(Person o) {
            //this:新传进来的对象    o:旧的对象
            int result = this.age-o.age;
            if(result==0) {
                result = this.name.compareTo(o.name);
            }
            return result;
        }
        
        @Override
        public int hashCode() {
            final int prime = 31;
            int result = 1;
            result = prime * result + age;
            result = prime * result + ((name == null) ? 0 : name.hashCode());
            return result;
        }
        @Override
        public boolean equals(Object obj) {
            if (this == obj)
                return true;
            if (obj == null)
                return false;
            if (getClass() != obj.getClass())
                return false;
            Person other = (Person) obj;
            if (age != other.age)
                return false;
            if (name == null) {
                if (other.name != null)
                    return false;
            } else if (!name.equals(other.name))
                return false;
            return true;
        }
        @Override
        public String toString() {
            return "Person [name=" + name + ", 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;
        }
        
    }
    View Code

      

      (5)Map的遍历方式

             假设有一个HashMap集合,存储的键和值都是String类型。名称叫hm。

             A:根据键找值(掌握)

                 a:获取所有键的集合

                 b:遍历键的集合,获取到每一个键

                 c:根据键找值

                 代码体现:

                 Set<String> set = hm.keySet();

                 for(String key : set) {

                    String value = hm.get(key);

                    System.out.println(key+"---"+value);

                 }

             B:根据键值对对象找键和值(理解)

                 a:获取所有键值对对象的集合

                 b:遍历键值对对象的集合,获取到每一个键值对对象

                 c:根据键值对对象获取键和值

                 代码体现:

                 Set<Map.Entry<String,String>> set = hm.entrySet();

                 for(Map.Entry<String,String> me : set) {

                    String key  = me.getKey();

                    String value = me.getValue();

                    System.out.println(key+"---"+value);

                 }

        (6)案例:

             A:统计一个字符串中每个字符出现的次数  

    import java.util.Set;
    import java.util.TreeMap;
    
    /**
     * “aabcbdeeeeedbddcc”,获取字符串中每一个字母出现的次数。要求结果:a(2)b(3)c(3)d(4)e(5)
     * 思路:字符串中的字符和数字存到treemap集合里,然后遍历输出
     */
    public class MapTest1 {
        public static void main(String[] args) {
            // 定义一个字符串(可以改进为键盘录入)
            String content ="aababcabcdabcde";
            // 定义一个TreeMap集合
            TreeMap<Character, Integer> tm = new TreeMap<Character, Integer>();
    
            //把字符串转换为字符数组
            char[] chs = content.toCharArray();
    
            //遍历字符数组,得到每一个字符
            for(char ch : chs){
                //拿刚才得到的字符作为键到集合中去找值,看返回值
                Integer i =  tm.get(ch);
    
                //是null:说明该键不存在,就把该字符作为键,1作为值存储
                if(i == null){
                    tm.put(ch, 1);
                }else {
                    //不是null:说明该键存在,就把值加1,然后重写存储该键和值
                    i++;
                    tm.put(ch,i);
                }
            }
    
            //定义字符串缓冲区变量
            StringBuilder sb=  new StringBuilder();
    
            //遍历集合,得到键和值,进行按照要求拼接
            Set<Character> set = tm.keySet();
            for(Character key : set){
                Integer value = tm.get(key);
                sb.append(key).append("(").append(value).append(")");
            }
    
            //把字符串缓冲区转换为字符串输出
            String result = sb.toString();
            System.out.println("result:"+result);
        }
    }
    View Code

         B:Map集合的嵌套存储和遍历

    import java.util.ArrayList;
    import java.util.HashMap;
    import java.util.Set;
    
    /*
     * List集合内元素为Map集合
     */
    public class Test {
    
        public static void main(String[] args) {
            //List嵌套List
            //创建集合对象
            ArrayList<ArrayList<String>> arrayList = new ArrayList<ArrayList<String>>();
            //创建元素对象
            ArrayList<String> list = new ArrayList<String>();
            list.add("吕布");
            list.add("赵云");
            list.add("典韦");
            list.add("关羽");
            list.add("马超");
            
            ArrayList<String> list2 = new ArrayList<String>();
            list2.add("高俅");
            list2.add("高衙内");
            list2.add("蔡京");
            list2.add("西门大官人");
            
            //将集合元素放入集合对象
            arrayList.add(list);
            arrayList.add(list2);
            
            System.out.println(arrayList);
            
            //List嵌套Map
            //创建集合对象
            ArrayList<HashMap<String, Person>> arrayList2 = new ArrayList<HashMap<String, Person>>();
            //创建元素对象
            HashMap<String, Person> hashMap = new HashMap<String, Person>();
            hashMap.put("五虎上将之一", new Person("关羽",38));
            hashMap.put("五虎上将之二", new Person("张飞",34));
            hashMap.put("五虎上将之三", new Person("赵云",32));
            hashMap.put("五虎上将之四", new Person("马超",30));
            hashMap.put("五虎上将之五", new Person("黄忠",60));
            
            HashMap<String, Person> hashMap2 = new HashMap<String, Person>();
            hashMap2.put("行者", new Person("武松",28));
            hashMap2.put("神行太保", new Person("戴宗",34));
            hashMap2.put("入云龙", new Person("公孙胜",32));
            hashMap2.put("九纹龙", new Person("史进",30));
            hashMap2.put("拼命三郎", new Person("石秀",29));
            //将集合元素添加到集合中
            arrayList2.add(hashMap);
            arrayList2.add(hashMap2);
    
            //迭代外层的ArrayList,里边的每个元素均为Map对象
            for (HashMap<String, Person> myMap : arrayList2) {
                //HashMap<String, Person> myMap
                //返回该map的所有key的Set集合
                Set<String> keySet = myMap.keySet();
                
                for (String key : keySet) {//迭代key的集合,获取每一个key
                    Person value = myMap.get(key);  //通过键获取值
                    //拼写字符串,完成对每个map中元素的打印
                    System.out.println(key+":"+value.getName()+" "+value.getAge());
                }
            }
        }
    
    }
    View Code
    import java.util.ArrayList;
    import java.util.HashMap;
    import java.util.Iterator;
    import java.util.Map;
    import java.util.Map.Entry;
    import java.util.Set;
    
    /*
     * 使用Map嵌套List
     */
    public class Test2 {
    
        public static void main(String[] args) {
            //创建map集合
            Map<String, ArrayList<Person>> map = new HashMap<String, ArrayList<Person>>();
            
            //创建集合元素
            String class1 = "0315基础班";
            ArrayList<Person> arrayList = new ArrayList<Person>();
            arrayList.add(new Person("唐嫣",28));
            arrayList.add(new Person("龙哥",23));
            arrayList.add(new Person("小龙女",16));
            arrayList.add(new Person("涛哥",31));
            
            String class2 = "0426就业班";
            ArrayList<Person> arrayList2 = new ArrayList<Person>();
            arrayList2.add(new Person("唐嫣",28));
            arrayList2.add(new Person("高圆圆",32));
            arrayList2.add(new Person("baby",26));
            arrayList2.add(new Person("熊黛林",32));
            
            //将集合元素添加到集合中
            map.put(class1, arrayList);
            map.put(class2, arrayList2);
            
            //遍历map集合
            Set<Entry<String,ArrayList<Person>>> entrySet = map.entrySet();
            
            Iterator<Entry<String, ArrayList<Person>>> iterator = entrySet.iterator();
            
            while (iterator.hasNext()) {
                Map.Entry<java.lang.String, java.util.ArrayList<cn.itcast2.Person>> entry = (Map.Entry<java.lang.String, java.util.ArrayList<cn.itcast2.Person>>) iterator
                        .next();
                String key = entry.getKey();
                ArrayList<Person> listValue = entry.getValue();
                System.out.println(key);
                Iterator<Person> iterator2 = listValue.iterator();
                while (iterator2.hasNext()) {
                    Person person = (Person) iterator2.next();
                    System.out.println(person);
                }
            }
        }
    
    }
    View Code
    import java.util.HashMap;
    import java.util.Map;
    import java.util.Set;
    
    /*
     * Map嵌套Map
     */
    public class Test3 {
    
        public static void main(String[] args) {
    
            Map<String, Map<String, Person>> map = new HashMap<String, Map<String,Person>>();
            
             Map<String, Person> innerMap = new HashMap<String, Person>();
             innerMap.put("师傅", new Person("唐三藏",34));
             innerMap.put("大师兄", new Person("孙悟空",500));
             innerMap.put("二师兄", new Person("朱悟能",800));
             innerMap.put("三师弟", new Person("沙悟净",600));
             
             Map<String, Person> innerMap2 = new HashMap<String, Person>();
             innerMap2.put("顽石", new Person("贾宝玉",14));
             innerMap2.put("十二金钗之一", new Person("薛宝钗",19));
             innerMap2.put("十二金钗之二", new Person("王熙凤",28));
             
             map.put("西游记", innerMap);
             map.put("红楼梦", innerMap2);
             
             Set<String> keySet = map.keySet();
             
             for (String key : keySet) {
                 Map<String, Person> value = map.get(key);
                 System.out.println(key);
                 Set<String> keySet2 = value.keySet();
                 for (String innerKey : keySet2) {
                     Person innerValuePerson = value.get(innerKey);
                     System.out.println(innerKey+":"+innerValuePerson);
                }
            }
        }
    
    }
    View Code

        (7)Map集合的体系

             Map

                 |--HashMap

                        |--LinkedHashMap

                 |--Hashtable

                 |--TreeMap

             A:HashMap和Hashtable的区别?

          HashMap键无序,不可重复,不安全,速度快,键和值都可以存放空值。

          Hashtable键无序,不可重复,安全,速度慢,键和值都不可以存放空值。

             B:LinkedHashMap的键的特点?

          键有序,不可重复。

    2:集合总结(什么时候使用谁?)

         是否键值对:

               是:Map

              是否排序:

                    是:TreeMap

                    否:HashMap

                   不知道,HashMap

             否:Collection

                 是否唯一:

                      是:Set

                           是否排序:

                             是:TreeSet

                             否:HashSet

                            不知道,HashSet

                     否:List

                        增删多:LinkedList

                        查询多:ArrayList

                        不知道,ArrayList

            不知道,用ArrayList

    3:集合体系总结

        集合:

           |--Collection

               |--List

                    |--ArrayList

                        底层数据结构是数组,查询快,增删慢。

                        线程不安全,效率高。

                    |--Vector

                        底层数据结构是数组,查询快,增删慢。

                        线程安全,效率低。

                    |--LinkedList

                        底层数据结构是链表,查询慢,增删快。

                        线程不安全,效率高。

               |--Set

                    |--HashSet

                        底层数据结构是哈希表。

                        如何保证唯一性?

                             依赖hashCode()和equals()

                        顺序:

                          先判断hashCode()值是否相同:

                                 是:继续走equals(),看返回值

                                      true:元素重复。不添加

                                      false:元素不重复。添加

                                 否:直接添加

                           |--LinkedHashSet

                           底层数据结构是链表和哈希表。

                               由链表保证有序(存储和取出一致)。

                               由哈希表保证元素唯一。

                          |--TreeSet

                        底层数据结构是二叉树。

                        如果保证唯一性?

                              根据返回值是否是0。

                        如何排序:

                             自然排序:Comparable

                             比较器排序:Comparator

            |--Map

                 |--HashMap

                      |--LinkedHashMap

                 |--Hashtable

                 |--TreeMap

    附:例子

    1、Map嵌套Map的例子

    import java.util.HashMap;
    import java.util.Set;
    
    /**
     * 使用集合进行以下分类:
         北京总部
              -JAVAEE班:5个
              -JAVASE班:8个
     上海分校
              -JAVAEE:4个
              -JAVASE:7个
    
     */
    public class Map3 {
        public static void main(String[] args) {
    
            //创建HashMap集合
            HashMap<String,HashMap<String,String>> hashMap=new HashMap<String,HashMap<String,String>>();
    
            //创建元素
            HashMap<String,String> innerHashMap1=new HashMap<String,String>();
            innerHashMap1.put("JavaEE班","5个");
            innerHashMap1.put("JavaSE班","8个");
    
            HashMap<String,String> innerHashMap2=new HashMap<String,String>();
            innerHashMap2.put("JavaEE班","4个");
            innerHashMap2.put("JavaSE班","7个");
    
            //添加元素
            hashMap.put("北京总部",innerHashMap1);
            hashMap.put("上海分校",innerHashMap2);
    
            //遍历输出
            Set<String> keySet=hashMap.keySet(); //外层key集合
            for(String key:keySet){
                System.out.println(key); //输出外层key
                HashMap<String,String> innerHashMap= hashMap.get(key);//获取外层key对应的Value值
                Set<String> inKeySet=innerHashMap.keySet();//内层key集合
                for(String innerkey:inKeySet){
                    String innerValue=innerHashMap.get(innerkey);
                    System.out.println("   "+innerkey+":"+innerValue);//输出内层key与内层Vakue
                }
    
            }
        }
    
    }
    View Code

    2、模拟地主洗牌发牌

    方法一:

    import java.util.ArrayList;
    import java.util.Collections;
    
    /*
     * 模拟斗地主洗牌发牌版本1
     */
    public class Test5 {
    
        public static void main(String[] args) {
    
            /*准备:
             * 花色:♠♥♦♣  ArrayList
             * 数字:3,4,5,6,7,8,9,10,J,Q,K,A,2  ArrayList
             * 大小王:☺☻
             * 得有一副54张的牌 ArrayList
             * 洗牌:
             *     打乱这副牌的顺序
             * 发牌:
             *     将54张牌分发到4个list手中,前三个17张,最后一个3张
             *     player    ArrayList
             *     player2    ArrayList
             *     player3    ArrayList
             *  dipai     ArrayList
             */
    
            //准备花色
            ArrayList<String> color = new ArrayList<String>();
            color.add("♠");
            color.add("♥");
            color.add("♦");
            color.add("♣");
    
            //准备数字
            ArrayList<String> number = new ArrayList<String>();
            Collections.addAll(number, "3","4","5","6","7","8","9","10","J","Q","K","A","2");
    
            //准备一副新牌
            ArrayList<String> cards = new ArrayList<String>();
    
            for (String thisColor : color) {
                for (String thisNumber : number) {
                    cards.add(thisColor+thisNumber);
                }
            }
            //加入大小王
            cards.add("大☻");
            cards.add("小☺");
    
            System.out.println(cards);
            //洗牌
            Collections.shuffle(cards);
            System.out.println(cards);
    
            //发牌
    
            //准备四个list作为3个玩家和底牌
            ArrayList<String> player = new ArrayList<String>();
            ArrayList<String> player2 = new ArrayList<String>();
            ArrayList<String> player3 = new ArrayList<String>();
            ArrayList<String> dipai = new ArrayList<String>();
    
            //遍历这副洗好的牌,遍历过程中,将牌发到三个玩家和dipai手中
            for (int i = 0; i < cards.size(); i++) {
    
                if(i>=51) {//分配底牌
                    dipai.add(cards.get(i));
                } else {
                    if(i%3==0) {
                        player.add(cards.get(i));
                    }else if(i%3==1) {
                        player2.add(cards.get(i));
                    }else {
                        player3.add(cards.get(i));
                    }
                }
            }
    
            //看牌
            System.out.println(player);
            System.out.println(player2);
            System.out.println(player3);
            System.out.println(dipai);
        }
    
    }
    View Code

    方法二:

    import java.util.ArrayList;
    import java.util.Collections;
    import java.util.HashMap;
    import java.util.TreeSet;
    
    /*
     * 斗地主洗牌发牌版本2:每个人手中的元素是有顺序的。
     */
    public class Test5 {
    
             /*准备:
             * 花色:♠♥♦♣  ArrayList
             * 数字:3,4,5,6,7,8,9,10,J,Q,K,A,2  ArrayList
             * 大小王:☺☻ 
             * !!!!!!!!定义一个map集合:用来将数字与每一张牌进行对应
             * 得有一副54张的牌 ArrayList里边为1-54的数  
             * 洗牌:
             *     打乱这副牌的顺序
             * 发牌:
             *     将54张牌分发到4个TreeSet手中,前三个17张,最后一个3张
             *     player    TreeSet
             *     player2   TreeSet
             *     player3   TreeSet
             *  dipai     TreeSet
             */
        
        public static void main(String[] args) {
    
            //准备花色
            ArrayList<String> color = new ArrayList<String>();
            color.add("♠");
            color.add("♥");
            color.add("♦");
            color.add("♣");
            
            //准备数字
            ArrayList<String> number = new ArrayList<String>();
            Collections.addAll(number, "3","4","5","6","7","8","9","10","J","Q","K","A","2");
            
            //定义一个map集合:用来将数字与每一张牌进行对应
            HashMap<Integer, String> hashMap = new HashMap<Integer, String>();
            
            int index = 1;
            for (String thisNumber : number) {
                for (String thisColor : color) {
                    hashMap.put(index++, thisNumber+thisColor);
                }
            }
            
            //加入大小王
            hashMap.put(index++, "小☺");
            hashMap.put(index++, "大☻");
            
            System.out.println(hashMap);
            
            //得有一副54张的牌 ArrayList里边为1-54的数的新牌
            ArrayList<Integer> cards = new ArrayList<Integer>();
            
            for (int i = 1; i <= 54; i++) {
                cards.add(i);
            }
            
            //洗牌
            Collections.shuffle(cards);
            System.out.println(cards);
            
            //创建三个玩家和底牌
            TreeSet<Integer> player = new TreeSet<Integer>();
            TreeSet<Integer> player2 = new TreeSet<Integer>();
            TreeSet<Integer> player3 = new TreeSet<Integer>();
            TreeSet<Integer> dipai = new TreeSet<Integer>();
            
            //遍历这副洗好的牌,遍历过程中,将牌发到三个玩家和dipai手中
            for (int i = 0; i < cards.size(); i++) {
                if(i>=51) {
                    dipai.add(cards.get(i));
                } else {
                    if(i%3==0) {
                        player.add(cards.get(i));
                    }else if(i%3==1) {
                        player2.add(cards.get(i));
                    }else {
                        player3.add(cards.get(i));
                    }
                }
            }
            
            //看牌
            for (Integer key : dipai) {
                System.out.print(hashMap.get(key)+", ");
            }
            System.out.println();
            for (Integer key : player) {
                System.out.print(hashMap.get(key)+", ");
            }
            System.out.println();
            for (Integer key : player2) {
                System.out.print(hashMap.get(key)+", ");
            }
            System.out.println();
            for (Integer key : player3) {
                System.out.print(hashMap.get(key)+", ");
            }
        }
    
    }
    View Code
  • 相关阅读:
    强大的Excel文件的导入导出类
    按某一字段分组取最大(小)值所在行的数据
    oracle 数据库创建脚本
    六十四卦的名称
    DirectX与OpenGL方面的经典电子书下载
    替换word文件内容
    asp.net里导出excel表方法汇总
    全角半角处理
    JavaScript正则表达式
    Asp.net config connectionString配置(转)
  • 原文地址:https://www.cnblogs.com/hezhiyao/p/7451165.html
Copyright © 2011-2022 走看看