2019-01-13

作者: DreamPath | 来源:发表于2019-01-13 22:40 被阅读7次

    基于Map集合重点整理

    Map集合

    1.1Map集合概念
    • Map集合是一种存放关系对象的对象的双列集合。
    img.png
    1.2Map集合的常用子类

    HashMap<K,V>

    • 1.数据存储方式:哈希表结构。
    • 2.存储情况:无序
    • 3.保证键的唯一性方式:需要重写键的hashCode()方法、equals()方法。

    LinkedHashMap<K,V>,是HashMap的一个子类。

    • 1.数据存储方式:哈希表结构+链表结构
      存储数据采用的哈希表结构+链表结构。
      (1.链表结构:保证元素的存取顺序一致。
      (2.哈希表结构:保证的键的唯一、不重复。
    • 3.同样需要重写键的 hashCode()方法、equals()方法

    注意:K, V泛型类型可以一致,也可以不一致。

    import java.util.HashMap;
    import java.util.Map;
    import java.util.Set;
    
    /**
     * @author lx
     * @date 2019/1/3 - 17:25
     * public V put(K key, V value) :  把指定的键与指定的值添加到Map集合中。
     * public V remove(Object key) : 把指定的键 所对应的键值对元素 在Map集合中删除,返回被删除元素的值。
     * public V get(Object key) 根据指定的键,在Map集合中获取对应的值。
     * boolean containsKey(Object key) 判断集合中是否包含指定的键。
     * public Set<K> keySet() : 获取Map集合中所有的键,存储到Set集合中。
     * public Set<Map.Entry<K,V>> entrySet() : 获取到Map集合中所有的键值对对象的集合(Set集合)
     */
    public class HashMapDemo {
        public static void main(String[] args) {
            HashMap<String, String> hashMap = new HashMap<>();
            //添加元素
            hashMap.put("冯小刚", "范冰冰");
            hashMap.put("李晨", "范冰冰");
            //如果键相同,值不同时,直接会覆盖前面的Value值。
            hashMap.put("冯小刚", "徐帆");
    
            hashMap.put("冯绍峰", "赵丽颖");
            hashMap.put("霍建华", "林心如");
            hashMap.put("杨幂", "刘恺威");
    
            System.out.println(hashMap);
            //{冯绍峰=赵丽颖, 霍建华=林心如, 冯小刚=徐帆, 李晨=范冰冰, 杨幂=刘恺威}
                //通过Key删除元素
                hashMap.remove("杨幂");
            System.out.println(hashMap);
            //{冯绍峰=赵丽颖, 霍建华=林心如, 冯小刚=徐帆, 李晨=范冰冰}
    
            //获取指定键key的value值
            String s = hashMap.get("霍建华");
            System.out.println(s);//林心如
    
            //判断集合中是否包含指定键
            System.out.println(hashMap.containsKey("杨幂"));//在这之前已经被删除了,返回false
    
            //判断集合中是否含有指定value值(一般很少用)
            System.out.println(hashMap.containsValue("范冰冰"));//true
    
            //获取集合中的所有键,并存储到集合中
            Set<String> set=hashMap.keySet();
            System.out.println(set);//[冯绍峰, 霍建华, 冯小刚, 李晨]
    
                //获取  键值对  对象的集合
            Set<Map.Entry<String,String>> set1=hashMap.entrySet();
            System.out.println(set1);//[冯绍峰=赵丽颖, 霍建华=林心如, 冯小刚=徐帆, 李晨=范冰冰]
    
            //遍历获取到的键值对的集合
            for (Map.Entry<String,String> ss:set1) {
                System.out.println(ss);
                /*
                冯绍峰=赵丽颖
                霍建华=林心如
                冯小刚=徐帆
                李晨=范冰冰
                 */
            }
        }
    }
    
    Entry键值对对象
    • Key(键)+Value(值)=Map集合中的Entry项。
    • Entry将键值对封装成了键值对 对象。方便了我们从每一个Entry对象获取对应的与对应的
    Map集合遍历键值对的方式

    通过集合中每个键值对(Entry)对象,获取键值对(Entry)对象中的键与值。

      1. 获取Map集合中,所有的键值对(Entry)对象,以Set集合形式返回。使用entrySet()方法。
      1. 遍历包含键值对(Entry)对象的Set集合,得到每一个键值对(Entry)对象。
      1. 通过键值对(Entry)对象,获取Entry对象中的键与值。使用getkey() 方法和getValue()。
    package hashMap_demo;
    
    import java.util.HashMap;
    
    import java.util.Map;
    import java.util.Set;
    
    /**
     * public K getKey() :获取Entry对象中的键。
     * public V getValue() :获取Entry对象中的值。
     * 在Map集合中也提供了获取所有Entry对象的方法:
     * public Set<Map.Entry<K,V>> entrySet() : 获取到Map集合中所有的键值对对象的集合(Set集合)
     */
    public class EntryDemo {
    
        public static void main(String[] args) {
            HashMap<Integer, String> map = new HashMap<>();
            map.put(20, "aa");
            map.put(18, "bb");
            map.put(20, "dd");
            map.put(25, "gg");
            map.put(28, "cc");
    
    //      使用hashMap集合对象调用entrySet方法获取Set的所有的entry对象,
            Set<Map.Entry<Integer, String>> entries = map.entrySet();
    
            for (Map.Entry<Integer, String> entry : entries) {
                int aInt = entry.getKey();
                String ss = entry.getValue();
                System.out.println(aInt + "cp是" + ss);
                //输出结果:
                //18cp是bb
                //20cp是dd
                //25cp是gg
                //28cp是cc
    
                //Map集合不能直接使用迭代器或者foreach进行遍历。但是转成Set之后就可以使用了
    
            }
        }
    }
    
    HashMap存储自定义类型键值
    • 练习:每位学生(姓名,年龄)都有自己的家庭住址。
    • 那么,既然有对应关系,则将学生对象和家庭住址存储到 map集合中。学生作为键, 家庭住址作为值。
    • 注意,学生姓名相同并且年龄相同视为同一名学生。
    package hashMap_demo;
    
    import java.util.Objects;
    
    /**
     * @author lx
     * @date 2019/1/13 - 18:15
     */
    public class Student {
        //创建变量
        private String name;
        private int age;
    //默认构造器
        public Student() {
        }
    //有参构造器
        public Student(String name, int age) {
            this.name=name;
            this.age=age;
        }
    //setter getter方法
        public void setName(String name) {
            this.name = name;
        }
    
        public String getName() {
            return name;
        }
    
        public int getAge() {
            return age;
        }
    
        public void setAge() {
            this.age = age;
        }
    //equals方法首先判断传入的是否与本类中的相同,相同则返回true
        public boolean equals(Object o) {
            if (this == o) {
                return true;
            }//其次再判断如果为空或者类名不同,则直接返回false
            if (o == null || getClass() != o.getClass()) {
                return false;
            }
            //将Object类型强转为Student类型,构成内容给的比较
            Student student = (Student) o;
            return age == student.age && Objects.equals(name, age);
        }
    //重写toString方法
        @Override
        public String toString() {
            return "Student{" +
                    "name='" + name + '\'' +
                    ", age=" + age +
                    '}';
        }
    //保证键值的唯一性
        @Override
        public int hashCode() {
            return Objects.hash(name,age);
        }
    }
    
    

    定义测试类:

    package hashMap_demo;
    
    import java.util.HashMap;
    import java.util.Map;
    import java.util.Set;
    
    /**
     * @author lx
     * @date 2019/1/13 - 18:39
     */
    public class Entry_Demo {
        public static void main(String[] args) {
            Map<Student,String> map=new HashMap<>();
            map.put(new Student("赵颖", 20), "河北");
            map.put(new Student("陈爽", 25), "湖南");
            map.put(new Student("张亚蓝", 29), "厦门");
            map.put(new Student("吕小童", 32), "陕西");
            map.put(new Student("赵颖",20),"山西");
            Set<Student> studentSet=map.keySet();
            for (Student key:studentSet
                 ) {
                String sss = map.get(key);
                System.out.println(key+"的住址是"+sss);
                /*输出结果:
                  Student{name='赵颖', age=20}的住址是山西
                  Student{name='陈爽', age=25}的住址是湖南
                  Student{name='吕小童', age=32}的住址是陕西
                  Student{name='张亚蓝', age=29}的住址是厦门*/
            }
        }
    
    }
    
    

    1.当给HashMap中存放自定义对象时,如果自定义对象作为key存在,这时要保证对象唯一,必须复写对象的hashCode和equals方法。
    2.如果要保证map中存放的key和取出的顺序一致,可以使用 java.util.LinkedHashMap 集合来存放。

    LinkedHashMap

    它是HashMap下面有一个子类LinkedHashMap,它是链表和哈希表组合的一个数据存储结构。
    特点:有序,不可重复

    package hashMap_demo;
    
    import java.util.LinkedHashMap;
    /**
     * @author lx
     * @date 2019/1/13 - 17:12
     */
    public class LinkedHashSetDemo {
        public static void main(String[] args) {
            LinkedHashMap<String,String> linkedHashMap=new LinkedHashMap<>();
                    linkedHashMap.put("赵丽颖","冯绍峰");
                    linkedHashMap.put("金玟岐","金玟岐");
                    linkedHashMap.put("咪咕","王少");
                    linkedHashMap.put("卡罗","扎西");
                    linkedHashMap.put("赵丽颖","李易峰");
            System.out.println(linkedHashMap);
            /*
            {赵丽颖=李易峰, 金玟岐=金玟岐, 咪咕=王少, 卡罗=扎西}
             */
        }
    }
    

    计算一个字符串中每个字符出现次数

    package hashMap_demo;
    
    import java.util.HashMap;
    import java.util.Scanner;
    
    /**
     * @author lx
     * @date 2019/1/13 - 17:41
     * 需求:
     * 计算一个字符串中每个字符出现次数
     * 1.从控制台获取字符串
     * 2.创建一个集合,一个作为为字符,一个为次数
     * 3.将字符串转化为字符,逐个遍历,判断是否是第一次出现
     * 4如果是第一次出现,Integer设置为1,不是则先获取上一次的value值。再加一之后存放
     */
    public class JiSuanZifuChuan {
    
        public static void main(String [] args){
            //从控制台录入字符串
            Scanner scanner=new Scanner(System.in);
            //获取字符串
            String next = scanner.nextLine();
    
            //创建一个集合,存储字符和次数
            HashMap<Character, Integer> hashMap = new HashMap<>();
    
            for (int i = 0; i < next.length(); i++) {
                //获取字符
                char c = next.charAt(i);
                if (!hashMap.containsKey(c)) {
                    hashMap.put(c, 1);
                } else {
                    //如果不是第一次,先取出来,然后再加一
                    Integer integer = hashMap.get(c);
    
                    hashMap.put(c, ++integer);
                }
    
            }
            System.out.println(hashMap);
        }
    }
    
    jdk9.0添加的优化

    1:of()方法只是Map,List,Set这三个接口的静态方法,其父类接口和子类实现并没有这类方法。比如 HashSet,ArrayList等;
    2:返回的集合是不可变的.

    public class Demo01 {  
      public static void main(String[] args) {  
          List<String> list = new ArrayList<>();        
            list.add("abc");
            list.add("def");     
            list.add("ghi");   
         System.out.println(list);  //[abc, def, ghi]  
           }
     }
    
    package hashMap_demo;
    
    import java.util.List;
    import java.util.Map;
    import java.util.Set;
    
    /**
     * @author lx
     * @date 2019/1/13 - 18:09
     */
    public class HelloJDK9 {
        public static void main(String[] args) {
    //        of方法设置后,集合不可变
            
            Set<String> str1 = Set.of("a", "b", "c");
    //        str1.add("c");    这里编译的时候不会错,但是执行的时候会报错,因为是不可变的集合
            System.out.println(str1);//[a, c, b]
            
            Map<String, Integer> str2 = Map.of("a", 1, "b", 2);
            System.out.println(str2);//{a=1, b=2}
            
            List<String> str3 = List.of("a", "b");
            System.out.println(str3);//[a, b]
        }
    }
    

    模拟斗地主洗牌发牌

    • 使用面向对象的方式实现斗地主洗牌发牌的操作
    package douDiZhu;
    
    import java.security.Key;
    import java.util.*;
    
    /**
     * @author lx
     * @date 2019/1/13 - 18:24
     *
     * 创建三个玩家
     * 
     * 创建牌
     * 构造牌盒
     * 洗牌
     * 发牌
     * 看牌
     *
     */
    public class DouDiZhu {
        public static void main(String[] args) {
            //创建牌数组
            String [] as={"3","4","5","6","7","8","9","10","J","Q","K","A","2"};
    //        创建花色
            String [] poker_color={"♠","♦","♣","♥"};
                //创建牌盒
            Map<Integer,String> map=new LinkedHashMap<>();
           //初始化索引为1
            int count=1;
    
            for (int i = 0; i <as.length; i++) {
                for (int j = 0; j <poker_color.length; j++) {
                    //将牌的数字和花色组合遍历
                    String sm=as[i]+poker_color[j];
                    //索引自增
                    map.put(count++,sm);
                }
            }
            //添加大王小王牌面
            map.put(count++,"小王🃏");
            map.put(count++,"大王🃏");
                    //将map集合对象的键存放在set集合中
                Set<Integer> set=map.keySet();
                //创建ArrayList集合
            ArrayList<Integer> arrayList=new ArrayList<>();
            //将set集合元素全部存入ArrayList集合中
            arrayList.addAll(set);
    
            //洗牌
            Collections.shuffle(arrayList);
    //        发牌
    //          创建三个玩家和三张底牌的索引
            ArrayList<Integer> Wanjia1=new ArrayList<>();
            ArrayList<Integer> wanjia2=new ArrayList<>();
            ArrayList<Integer> wanjia3=new ArrayList<>();
            ArrayList<Integer> dipaiNo=new ArrayList<>();
                    //给每个玩家发牌
            for (int i = 0; i <arrayList.size() ; i++) {
                Integer integer=arrayList.get(i);
                if (i>=51) {
                    dipaiNo.add(integer);
                } else{
                    if (i%3==0){
                    Wanjia1.add(integer);
                    } else if (i%3==1) {
                        wanjia2.add(integer);
                    }else {
                        wanjia3.add(integer);
                    }}
            }
                    //将手中的牌按照大小排序
            Collections.sort(Wanjia1);
            Collections.sort(wanjia2);
            Collections.sort(wanjia3);
            Collections.sort(dipaiNo);
    
                //创建玩家的牌面集合
            ArrayList play1=new ArrayList();
            ArrayList play2=new ArrayList();
            ArrayList play3=new ArrayList();
            ArrayList dipai=new ArrayList();
                //遍历 根据键来获得值(牌面)
            for (Integer is:Wanjia1) {
                String value = map.get(is);
                play1.add(value);
            } for (Integer is:wanjia2) {
                String value = map.get(is);
                play2.add(value);
            } for (Integer is:wanjia3) {
                String value = map.get(is);
                play3.add(value);
            }for (Integer is:dipaiNo) {
                String value = map.get(is);
                dipai.add(value);
            }
            //看牌
            System.out.println("哈儿"+play1);
            System.out.println("逗逼" +play2);
            System.out.println("傻子"+play3);
            System.out.println("底牌"+dipai);
        }
    }
    
    

    相关文章

      网友评论

        本文标题:2019-01-13

        本文链接:https://www.haomeiwen.com/subject/ngkrdqtx.html