zoukankan      html  css  js  c++  java
  • java基础第十四篇之Map


     一,Map集合的特点:
     * 
     * 1.Map集合和Collection集合,没有关系
     * 
     * 2.Map集合的元素是成对存在(夫妻关系)
     *         Collection集合的元素是独立存在的(单身关系)
     * 
     * 3.Map集合的元素不能重复(是元素的key值不能重复)
     * 
     * 总结:
     *         Collection集合我们一般称为单列集合
     *         Map集合我们称为双列集合
     * 二,Map接口下常用的实现类
     * 
     * HashMap<K,V>:底层是哈希表结构,无序的(存取顺序不一致)
     * 
     * 
     * LinkedHashMap<K,V>:底层链表+哈希表结构,有序的(存取顺序一致)
     *             这里<K,V>是两个泛型,这里的K和V可以相同 也可以不同
     *             K代表键的类型,V代表的是值的类型
     * 
     * 以上所有的实现类,保证键的唯一性(键不能重复),那么我们需要重写K这种类型的hashCode和equals方法
     *         比如:K的类型是String,Integer...(java提供的类型),那么我们不需要管他
     *             K的类型是Person,Dog等自定义类型 那么我们就需要重写hashCode和equals方法
     * 
     * 三,Map接口中定义的常用方法:
     * 
     * 1.增加:
     *         public V put(K key,V value);//向Map集合中添加一个元素(键值对)
     *         返回值:表示被新的键值对 覆盖的那个旧的键值对的值
     *             如果没有覆盖,返回值是null
     * 
     * 2.删除:
     *         public V remove(Object key);//删除一个键值对(根据键来删除)
     * 
     * 3.改:实际上就是put方法,只要put的时候键和map集合中原有的键重复,就可以达到改的目的
     * 
     * 4.查
     *         public V get(Object key);//根据键 来查找键所对应的值
     
     
     public interface InterfaceA {
        public abstract void showA();
        
        interface InterfaceB{//内部接口
            public abstract void showB();
        }
    }

    //定义一个类 去实现接口

    class MyClass1 implements InterfaceA{

        @Override
        public void showA() {
            // TODO Auto-generated method stub
            
        }

    //    @Override
    //    public void showA() {
    //        // TODO Auto-generated method stub
    //        
    //    }
    }

    class MyClass2 implements InterfaceA.InterfaceB{

        @Override
        public void showB() {
            // TODO Auto-generated method stub
            
        }
        
    }


    /*
     * 1.因为Map集合 和Collection集合 没有继承关系
     *      map集合中是没有迭代器
     *  
     * 2.java为map集合提供了另外两种迭代的方式:
     *         方式一:以键找值的方法:
     *             获取所有的键的集合 map.keySet();
     *         方式二:键值对的方式
     *             public Set<Map.Entry<K,V>> entrySet()
     */
     
     //创建内部类对象
            //OuterClass.InnerClass oi = new OuterClass().new InnerClass();
            Map<String, Integer> map = new HashMap<String, Integer>();
            map.put("张三", 18);
            map.put("李四", 28);
            map.put("王五", 38);
            map.put("赵六", 48);
            //1.获取map集合的entry 集合
            Set<Map.Entry<String, Integer>> entries = map.entrySet();
            //2.用迭代器 遍历这个entries这个Set集合
            Iterator<Map.Entry<String, Integer>> it = entries.iterator();
            //3.遍历
            while(it.hasNext()){
                Map.Entry<String, Integer> entry = it.next();
                //一个entry中 有两个属性
                String key = entry.getKey();
                Integer value = entry.getValue();
                System.out.println(key+"="+value);
                
            }
            
     
     * 练习1:使用map存储:键为学号,值为一个学生的对象,学生对象有属性(姓名,年龄)
     * 
     * 
     * 练习2:使用map存储:键为学生(姓名,年龄)值为学生自己的家庭住址。
     *         Map<Student,String>
     
     public class MapDemo {
        public static void main(String[] args) {
            //定义一个Map集合 存储键为学生(姓名,年龄)值为学生自己的家庭住址。
            Map<Student, String> map = new HashMap<Student, String>();
            //向集合添加数据
            map.put(new Student("王宝强", 40), "北京五环外");
            map.put(new Student("谢霆锋", 50), "北京180环外");
            map.put(new Student("马蓉", 45), "上海交通路");
            map.put(new Student("郭德纲", 55), "广州德云社");
            map.put(new Student("马蓉", 45), "我家");
            //map判断键重复不重复,是通过hashCode和equals方法
            //如果 我要求一个学生的姓名和年龄一样 就认为是同一个学生
            //遍历集合 keySet entrySet
            //1.获取entry的集合
            Set<Map.Entry<Student, String>> entries = map.entrySet();
            //2.迭代器遍历 foreach
            for (Map.Entry<Student, String> entry : entries) {
                Student key = entry.getKey();
                String value = entry.getValue();
                System.out.println(key+"="+value);
            }
        }
    }


    /*
     * LinkedHashMap: 采用链表+哈希表结构
     *         元素是有序的
     
      Collection和Map都可以嵌套
     * 
     * ArrayList<ArrayList<String>>
     * 
     * ArrayList<Map<K,V>>
     * 
     * Map<String,ArrayList<String>>
     * 
     * Map<String,Map<String,Student>>
     * 
     * 比如我们传智博客学生(有iOS Android UI JavaEE)
     *        Map<学号,学生> UI = new HashMap<学号,学生>();
     *
     *        Map<学号,学生> JavaEE = new HashMap<学号,学生>();
     *
     *        Map<学号,学生> android = new HashMap<学号,学生>();
     *
     *        
     *         ArrayList<Map<学号,学生>>  al= new ....
     *             al.add(UI);
     *             al.add(JavaEE);
     *             al.add(android);
     * 
     *         Map<学院名,Map<学号,学生>> map = new ....
     *             map.put("UI学院",UI);
     *             map.put("JavaEE学院",JavaEE);
     *             map.put("安卓学院",android);
     * 
     *         
     * 
     * 
     * 
     */
    public class MapMapDemo {

        public static void main(String[] args) {
            // TODO Auto-generated method stub
            //1.创建一个UI学院的map集合
            Map<String, Student> uiMap = new HashMap<String, Student>();
            uiMap.put("黑马001", new Student("小丽", 18));
            uiMap.put("黑马003", new Student("小美", 19));
            uiMap.put("黑马004", new Student("小雨", 20));
            //2.创建一个JavaEE学院map集合
            Map<String, Student> eeMap = new HashMap<String, Student>();
            eeMap.put("黑马001", new Student("小诗", 18));
            eeMap.put("黑马002", new Student("小公", 19));
            eeMap.put("黑马004", new Student("小龙", 20));
            //3.创建一个android学院map集合
            Map<String, Student> anMap = new HashMap<String, Student>();
            anMap.put("黑马002", new Student("小k", 18));
            anMap.put("黑马003", new Student("小Q", 19));
            anMap.put("黑马004", new Student("小A", 20));
            //4.定义一个存储所有学院名字和map对象的集合
            Map<String,Map<String, Student>> map = new HashMap<String, Map<String,Student>>();
            map.put("UI学院", uiMap);
            map.put("EE学院", eeMap);
            map.put("AN学院", anMap);
            //遍历map 打印是每一个学生
            //1.keySet() 2.entrySet()
            Set<Map.Entry<String,Map<String, Student>>> entries = map.entrySet();
            //2.遍历 entries 迭代器,foreach
            Iterator<Map.Entry<String,Map<String, Student>>> it = entries.iterator();
            //标准代码
            while(it.hasNext()){
                Map.Entry<String,Map<String, Student>> entry = it.next();
                String key = entry.getKey();
                Map<String, Student> valueMap = entry.getValue();
                //遍历value这个map集合 keySet entrySet
                Set<Map.Entry<String, Student>>  xyentries = valueMap.entrySet();
                //迭代器 foreach
                Iterator<Map.Entry<String, Student>> xyit = xyentries.iterator();
                //标准代码
                while(xyit.hasNext()){
                    Map.Entry<String, Student> xyentry = xyit.next();
                    String xykey = xyentry.getKey();
                    Student xyValue = xyentry.getValue();
                    //System.out.println("学院,学号,学生名字,学生年龄");
                    System.out.println(key+"-"+xykey+"-"+xyValue.getName()+"-"+xyValue.getAge());
                }
                    
            }
            
            
            
            
        }

    }


    * Collections集合工具类中的两个方法:
     * 
     * public static void sort(List<T> list);//按照自然顺序(123 321 abc cba)排序一个List集合
     * 
     * public static void shuffle(List<?> list);//打乱集合中顺序
     
     * 可变参数: 这里说的可变 不是参数的数据类型 而是参数的个数
     *         JDK1.5之后的新特性
     * 
     *         格式: public void showNum(int... num){
     * 
     *              }
     * 
     * 注意事项:
     *         当一个方法具有多个参数,而且其中有一个是可变参数,那么可变参数必须写到 参数的最后一个
     *     
     
     public class VariableArgDemo01 {

        public static void main(String[] args) {
            // TODO Auto-generated method stub
    //        show(1);
    //        show(1,2);
    //        show(1,2,3);
            show(1,2,3,4,5);
        }
        //定义带有可变参数的方法
        public static void show(int count,int... num){
                //在方法中怎么获取实际传递进来的参数,可变参数本质就是一个数组
                System.out.println(num.length);
                for (int i = 0; i < num.length; i++) {
                    System.out.println(num[i]);
                }
            }
        }


    /*
     * 1.定义自定义规则的map集合
     * 
     * 2.产生一副牌(存储的是序号)
     * 
     * 3.洗牌(序号的集合)
     * 
     * 4.发牌(发的就是序号)
     * 
     * 5.要求三个玩家以及地主牌进行排序(sort方法)
     * 
     * 6.看牌(根据序号从自定义的map集合中取值)
     * 
     * 
     */
    public class DouDiZhuDemo {

        public static void main(String[] args) {
            // TODO Auto-generated method stub
            //1.定义规则的map集合
            Map<Integer, String> map = new LinkedHashMap<Integer, String>();
            //2.定义一个牌集合
            ArrayList<Integer> cards = new  ArrayList<Integer>();
            //添加牌 一张牌 数值+花色
            String[] nums = {"3","4","5","6","7","8","9","10","J","Q","K","A","2"};
            String[] colors = {"♠","♥","♣","♦"};
            //拼接一个张牌 
            int id = 54;//1234
            for (String num : nums) {
                for (String color : colors) {
                    String card = color+num;
                    map.put(id, card);
                    cards.add(id);
                    id--;
                    //System.out.println(card);
                }
            }
            //添加大王小王
            map.put(2, "小S");
            cards.add(2);
            map.put(1, "大S");
            cards.add(1);
            //3.洗牌
            Collections.shuffle(cards);
            //4.发牌
            //定义三个集合
            ArrayList<Integer> p1 = new ArrayList<Integer>();
            ArrayList<Integer> p2 = new ArrayList<Integer>();
            ArrayList<Integer> p3 = new ArrayList<Integer>();
            //定义地主牌的集合
            ArrayList<Integer> dp = new ArrayList<Integer>();
            //遍历54张牌
            for (int i = 0; i < cards.size(); i++) {
                Integer card = cards.get(i);
                //如果是最后三张,不发,保存到地主牌的集合中
                //i 53 52 51
                if(i>=51){
                    //不发
                    dp.add(card);
                    
                }else{
                    //0 p1 1 p2  2 p3  3 p1
                    if(i%3==0){
                        //给p1发牌
                        p1.add(card);
                    }else if(i%3==1){
                        p2.add(card);
                    }else{
                        p3.add(card);
                    }
                }
            }
            //5.排序
            Collections.sort(p1);
            Collections.sort(p2);
            Collections.sort(p3);
            Collections.sort(dp);
            //看牌
            lookCards(p1,map);
            lookCards(p2,map);
            lookCards(p3,map);
            lookCards(dp,map);
        }
        /*
         * 看牌
         */
        public static void lookCards(ArrayList<Integer> cards,Map<Integer, String> map){
            //根据每一张的编号从 map中取出打印
            for (Integer id : cards) {
                String card = map.get(id);
                System.out.print(card+" ");
            }
            System.out.println();
        }
        

    }

    /*

    Map 里面有个方法:  boolean containsKey : 判断Map集合中是否包含指定值 

    HashSet:底层是哈希算法实现.
    LinkedHashSet:底层是链表实现,但是也是可以保证元素唯一,和HashSet原理一样.

    TreeSet:底层是二叉树算法实现.
    一般在开发的时候不需要对存储的元素排序,所有在开发的时候大多用HashSet,HashSet的效率比较高
    TreeSet在面试的时候比较多,问你有几种排序方式,和几种排序方式的区别?

     2.    TreeSet总结
    1). TreeSet的特点
    (1). 可以对元素进行排序
           有两种排序方式。
    (2). TreeSet保证元素的唯一性依据
           在实现的Comparable的compareTo或者Comparator的compare方法中,如果这两个方法的返回值为0,那么TreeSet就认为这两个元素一样。按照Set的唯一性规则,在一次重复的元素不能被添加到TreeSet这个集合中。
    2). TreeSet的两种排序方式
    (1). 让元素本身具有比较性
           元素本身要实现Comparable接口并实现里面的compareTo方法以保证元素本身具有比较性
    (2). 让容器自身具有比较性
           当元素本身不具有比较性或者具备的比较性不是所需要的,就在TreeSet建立实例的时候,传入Comparator接口的实现子类的实例。这个Comparator子类必须实现compare方法。
     
    (3). 元素的可存储性
    [1]. 自定义的类,如果重写了hashCode和equals两个方法,可以存入HashSet容器
    [2]. 自定义的类,如果实现了Comparable的compareTo()方法,可以存入TreeSet容器。
    【总结】如果自定义的类既重写了hashCode和equals,又实现了compareTo,那么这个类的元素既可以存入HashSet容器,也可以存入TreeSet容器。

    Map
        HashMap :底层是哈希算法,针对键
            LinkedHashMap:底层是链表,针对键.
        
        TreeMap:底层是二叉树算法,针对键.(开发中HashMap比较多)
    Collection
         List(存取有序,有索引,可以重复)
            ArrayList:底层是数组实现的,线程不安全,查找和修改快,增和删比较慢.
            LinkedList:底层是链表实现的,线程不安全,增和删比较快,查找和修改比较慢
            Vector : 底层是数组实现的,线程安全的,无论增删改查都慢.
        
        如果查找和修改多,用ArrayList.
        如果增和删多,用LinkedList.
        如果都多,用ArrayList
        Set(存取无序,无索引,不可以重复)
            HashSet
                LinkedHashSet
            TreeSet

            
    //获取字符串中每个字符的个数
    public class Demo11 {
        public static void main(String[] args) {
            String sbc = "kalsdjfoisoigjsljlfklkadaooaijfa";
            //将字符串变成一个字符数组
            char[] chs = sbc.toCharArray();
            //遍历这个字符数组,一个一个的进行比较,但是要计算数量,那么用那个集合好点?Map,为什么Map,可以显示效果,'a',1  'b'2
            Map<Character, Integer> map = new HashMap<>();
            
            //遍历字符数组
            for(char c : chs) {
                //判断Map里面有没有键是c的?
                boolean flag = map.containsKey(c);
                //代表map里面有键是c的,那么数量就需要++
                if(flag) {
                    //在原先的数量上加上1,根据键找值
                    map.put(c, map.get(c)+1);
                }else {
                    //就是map集合里面没用这个字符,如果说是没有的话,那么说明是第一次.
                    map.put(c, 1);
                }
                
            }
            System.out.println(map);
            
        }
    }

  • 相关阅读:
    [RxJS] defer() lazy evaluation
    [React] as component prop
    [Compose] Compose exercises
    MAC开发NDK非常的简单
    Android之zip包换肤(极力推荐)
    Android之获取sdcard卡的信息
    Android之Volley使用
    Android之与当前连接的wifi进行文件夹的浏览与传输
    android之获得当前连接wifi的名字
    android之截屏(包括截取scrollview与listview的)
  • 原文地址:https://www.cnblogs.com/haizai/p/11108864.html
Copyright © 2011-2022 走看看