JAVASE-21:Map集合及其子类HashMap 、Hashtable、LinkedHashMap 、TreeMap

集合Map

有一种数据比较常见,比如一个学号对应一个学生,这种键值映射关系的数据,为了方便操作,给我们提供了另一种容器,叫做Map:称之为双列集合,有键 有映射值,一个键只能映射一个值,键是唯一的,如果键相同,那么值会覆盖。
所有的双列集合的数据结构,只跟键有关,跟值没有关系。

Map接口和Collection接口的不同
Map是双列的,Collection是单列的;
Map的键唯一,Collection的子体系Set是唯一的;
Map集合的数据结构针对键有效,跟值无关;Collection集合的数据结构是针对元素有效。

接口Map<K,V>
K-此映射所维护的键的类型
V-映射值类型
实现类 HashMap<K,V> 、Hashtable<K,V>、 LinkedHashMap<K,V> 、 TreeMap<K,V>


1.HashMap<K,V>

键的数据结构是哈希表,所以键无序且唯一。允许null值 null键。线程不安全,效率高。所有的双列集合的数据结构,只跟键有关,跟值没有关系。当键相同,值就覆盖,返回的是上一次这个键所映射的那个旧值。

hm.put(“ K key”,“ V value”); 添加功能,这个其实还有另一个功能:替换—
如果键是第一次存储,就直接存储元素,返回null;
如果键不是第一次存在,就用值把以前的值替换掉,返回以前的值

hm.clear(); 清空

hm.remove(K); 根据键值删除,返回值是键所对应的值

hm.size(); 集合长度

判断相关

判断是否有某个键 hm.containsKey(K);

判断是否有某个值 hm.containsValue(V);

通过键获取值 hm.get(K); 如果没有这个键返回null

通过键获取值 hm.getOrDefault(K,备用V); 如果没有这个键返回备用值

判断是否为空 hm.isEmpty();

hm.values(); 获取所有值得集合 放入collection

public static void main(String[] args) {
    HashMap<String, String> hm = new HashMap<>();
    hm.put("米兰", "马尔蒂尼");
    hm.put("国米", "萨内蒂");
    hm.put("尤文", "皮耶罗");
    hm.put("罗马", "托蒂");
    // hm.clear();清空集合
    // hm.size() 集合的长度
    System.out.println(hm.size());
    // 返回的是那个键,所对应的值。
    String s = hm.remove("罗马");
    System.out.println(hm);
    System.out.println(s);
    System.out.println(hm.containsKey("佛罗伦萨"));// false
    System.out.println(hm.containsValue("马尔蒂尼"));// true
    System.out.println(hm.isEmpty());// false
    //通过键来获取值
    System.out.println(hm.get("国米"));// 萨内蒂
    //通过键来获取值,没有对应的值,可以给一个默认值。
    System.out.println(hm.getOrDefault("佛罗伦萨", "巴蒂斯图塔"));// 巴蒂斯图塔
}
遍历双链集合

方式一:按照键找值,拿出所有键放入set集合,hm.keySet(); 获取所有键的集合,最后hm.get(K)按键找值。

方式二:将键值对,看作一个整体,把键值对 对象获取出来,然后使用键值对,对象中的方法获取键和值。

Map.Entry<String, String> ,K getKey () 返回与此项对应的键。 V getValue () 返回与此项对应的值。

方法三:forEach();

public static void main(String[] args) {
    HashMap<String, String> hm = new HashMap<>();
    hm.put("皇马", "BBC");
    hm.put("巴萨", "MSN");
    hm.put("拜仁", "罗贝里");
    hm.put("曼联", "林加德");
    // values();获取所有值的集合
    Collection<String> values = hm.values();
    System.out.println(values);
    
    // 遍历双列集合
    // 第一种:键找值  keySet();获取所有键的集合
    Set<String> keySet = hm.keySet();
    for (String key : keySet) {
        String value = hm.get(key);//按照键找值
        System.out.println(key + "===" + value);
    }
    System.out.println("=====================================");
    
    //第二种:把键值对,看做一个整体,把键值对,对象获取出来,然后使用键值对,对象中的方法来获取键和值。
    Set<Map.Entry<String, String>> entries = hm.entrySet();
    for (Map.Entry<String, String> entry : entries) {
        //System.out.println(entry);
        String key = entry.getKey();// 返回与此项对应的键
        String value = entry.getValue();// 返回与此项对应的值
        System.out.println(key + "===" + value);
    }
    
    //方法三:
    System.out.println("================================");
    hm.forEach(new BiConsumer<String, String>() {
        @Override
        public void accept(String key, String value) {
            System.out.println(key + "===" + value);
        }
    });
}

所有的双列集合的数据结构,只跟键有关,跟值没有关系。

理解:new student虽然设置的成员变量name、age相同,但是两个都可以存进去,没有重写equales()和hashcode()方法,比较就认为地址值不同。

public static void main(String[] args) {
    // 存储键是Student类型,值是String类型
    HashMap<Student, String> hm = new HashMap<>();
    hm.put(new Student("张三", 23),"s001" );
    hm.put(new Student("张三", 23),"s001" );
    hm.put(new Student("王五", 25),"s002" );
    hm.put(new Student("赵六", 26),"s003" );
    hm.put(new Student("田七", 27),"s004" );
    for (Map.Entry<Student, String> entry : hm.entrySet()) {
        Student key = entry.getKey();
        String value = entry.getValue();
        System.out.println(key.getName()+"#"+key.getAge()+"===="+value);
    }
}

2.Hashtable<K,V>

和HashMap<K,V>的区别:

Hashtable<K,V> 不允许null值 和 null键,线程安全,效率低。

public static void main(String[] args) {
    HashMap<String, String> stringStringHashMap = new HashMap<>();
    stringStringHashMap.put(null,null);
    System.out.println(stringStringHashMap);

    Hashtable<String, String> stringStringHashtable = new Hashtable<>();
    //stringStringHashtable.put(null,"abc");
    stringStringHashtable.put("abc", null);//NullPointerException
}

3.LinkedHashMap<K,V>

键的数据结构是链表和哈希表,键唯一且有序,链表保证有序,哈希表保证唯一。

public static void main(String[] args) {
    // LinkedHashMap 键的数据结构是链表和哈希表,键唯一且有序,链表保证有序,哈希表保证唯一。
    LinkedHashMap<String, String> hm = new LinkedHashMap<>();
    hm.put("拜仁", "莱万");
    hm.put("拜仁","克洛泽");
    hm.put("多特", "哈兰德");
    hm.put("莱比锡", "维尔纳");
    hm.put("勒沃库森", "哈佛茨");
    System.out.println(hm);
    // {拜仁=克洛泽, 多特=哈兰德, 莱比锡=维尔纳, 勒沃库森=哈佛茨}
}

4.TreeMap<K,V>

TreeMap 键不允许插入null, 键的数据结构是红黑树,可保证键的排序和唯一性,排序分为自然排序和比较器排序 , 线程是不安全的效率比较高。

public static void main(String[] args) {
        TreeMap<Integer, String> treeMap = new TreeMap<>();
        treeMap.put(7, "舍甫琴科");
        treeMap.put(3, "马尔蒂尼");
        treeMap.put(1, "迪达");
        treeMap.put(21, "皮尔洛");
        treeMap.put(10, "鲁伊科斯塔");
        treeMap.put(9, "因扎吉");
        treeMap.put(2, "卡福");
        treeMap.put(13, "内斯塔");
        treeMap.put(5, "科斯塔库塔");
        treeMap.put(8, "加图索");
        Set<Integer> integers = treeMap.keySet();
        for (Integer integer : integers) {
            System.out.println(integer+"-"+treeMap.get(integer));
        }
        System.out.println();
    
        TreeMap<String, Integer> Milan = new TreeMap<>();
        Milan.put("Shevchenko",7);
        Milan.put("KaKa",22);
        Milan.put("Cafu",2);
        Milan.put("Gattuso",8);
        Milan.put("Nesta",13);
        Milan.put("Tomasson",15);
        Milan.put("Costa",10);
        Set<Map.Entry<String, Integer>> entries = Milan.entrySet();
        for (Map.Entry<String, Integer> entry : entries) {
            String key = entry.getKey();
            Integer value = entry.getValue();
            System.out.println(key +"-"+ value);
        }
    }

自然排序

public static void main(String[] args) {
    // 键是Student类型,值是String类型
    // 按照学生的年龄大小来排序
    TreeMap<Student, String> treeMap = new TreeMap<>();
    treeMap.put(new Student("张国荣", 18), "s001");
    treeMap.put(new Student("张国荣", 18), "s001");
    treeMap.put(new Student("张世豪", 15), "s004");
    treeMap.put(new Student("张世荣", 17), "s002");
    treeMap.put(new Student("张学友", 18), "s003");
    treeMap.put(new Student("张三", 18), "s004");
    treeMap.put(new Student("张曼玉", 17), "s005");
    /* System.out.println(treeMap); */
    treeMap.forEach(new BiConsumer<Student, String>() {
        @Override
        public void accept(Student student, String s) {
            System.out.println(student.getName()+"=="+student.getAge()+"========="+s);
        }
    });
}
@Override
public int compareTo(Student o) {
    int num=this.age-o.age==0?this.name.compareTo(o.name):this.age-o.age;
    return num;
}

比较器排序

public static void main(String[] args) {
    TreeMap<Student, String> treeMap = new TreeMap<>(new Comparator<Student>() {
        @Override
        public int compare(Student s1, Student s2) {
            int num = s1.getAge() - s2.getAge() == 0 ? s1.getName().compareTo(s2.getName()) : s1.getAge() - s2.getAge();
            return num;
        }
    });
    treeMap.put(new Student("张国荣", 18), "s001");
    treeMap.put(new Student("张国荣", 18), "s001");
    treeMap.put(new Student("张世豪", 15), "s004");
    treeMap.put(new Student("张世荣", 17), "s002");
    treeMap.put(new Student("张学友", 18), "s003");
    treeMap.put(new Student("张三", 18), "s004");
    treeMap.put(new Student("张曼玉", 17), "s005");
    // System.out.println(treeMap);
    treeMap.forEach(new BiConsumer<Student, String>() {
        @Override
        public void accept(Student student, String s) {
            System.out.println(student.getName() + "==" + student.getAge() + "=========" + s);
        }
    });
}

练习1:

统计字符串中字符出现次数

“aababcabcdabcde”, 获取字符串中每一个字母出现的次数

要求结果:a(5) b(4) c(3) d(2) e(1)
a—5
b—4
c—3
d—2
e—1
每个字符和它出现的次数,是键值映射关系

public static void main(String[] args) {
    Scanner sc = new Scanner(System.in);
    System.out.println("请输入一段字符串");
    String str = sc.nextLine();
    // 每个字符和它出现的次数,是键值映射关系
    HashMap<Character, Integer> hashMap = new HashMap<>();
    for (int i = 0; i < str.length(); i++) {
        char ch = str.charAt(i);
        if (!hashMap.containsKey(ch)) {
            hashMap.put(ch, 1);
        } else {
            Integer value = hashMap.get(ch);
            value++;
            // 键相同,值覆盖
            hashMap.put(ch, value);
        }
    }
    System.out.println(hashMap);
    // 遍历集合拼串
    StringBuilder sb = new StringBuilder();
    for (Map.Entry<Character, Integer> entry : hashMap.entrySet()) {
        Character key = entry.getKey();
        Integer value = entry.getValue();
        sb.append(key).append("(").append(value).append(")").append(" ");
    }
    String s = sb.toString();
    System.out.println(s);

练习2:集合嵌套 - - - 先看小的关系 再看大的关系

HashMap嵌套HashMap

public static void main(String[] args) {
        /* *       
           基础班
              张三    20
              李四    22
           就业班
              王五    21
              赵六    23
        * */

        //HashMap 嵌套 HashMap
        HashMap<String, Integer> jcMap = new HashMap<>();
        jcMap.put("张三",20);
        jcMap.put("李四",22);
        HashMap<String, Integer> jyMap = new HashMap<>();
        jyMap.put("王五", 21);
        jyMap.put("赵六", 23);
        HashMap<String, HashMap<String, Integer>> maxMap = new HashMap<>();
        maxMap.put("基础班",jcMap);
        maxMap.put("就业班",jyMap);
        
    	Set<String> keySet = maxMap.keySet();
        for (String s : keySet) {
            System.out.println(s);
            HashMap<String, Integer> minMap = maxMap.get(s);
            Set<String> keySet1 = minMap.keySet();
            for (String s1 : keySet1) {
                System.out.println("\t" +s1+" "+ minMap.get(s1));
            }
        }
    }

HashMap嵌套ArrayList

public static void main(String[] args) {
    /* *   
     三国演义
       吕布
       周瑜
     笑傲江湖
       令狐冲
       林平之
     神雕侠侣
       郭靖
       杨过
    * */
    ArrayList<String> sgList = new ArrayList<>();
    sgList.add("吕布");
    sgList.add("周瑜");

    ArrayList<String> xaList = new ArrayList<>();
    xaList.add("令狐冲");
    xaList.add("林平之");

    ArrayList<String> sdList = new ArrayList<>();
    sdList.add("郭靖");
    sdList.add("杨过");

    LinkedHashMap<String, ArrayList<String>> hashMap = new LinkedHashMap<>();
    hashMap.put("三国演义", sgList);
    hashMap.put("笑傲江湖", xaList);
    hashMap.put("神雕侠侣", sdList);
    
    Set<String> keySet = hashMap.keySet();
    for (String s : keySet) {
        System.out.println(s);
        ArrayList<String> list = hashMap.get(s);
        for (String s1 : list) {
            System.out.println("\t" + s1);
        }
        System.out.println();
    }
}

ArrayList嵌套HashMap

public static void main(String[] args) {
    /*
    周瑜-- - 小乔
    吕布-- - 貂蝉

    郭靖-- - 黄蓉
    杨过-- - 小龙女

    令狐冲-- - 任盈盈
    林平之-- - 岳灵珊
    */
    HashMap<String, String> sgMap = new HashMap<>();
    sgMap.put("周瑜","小乔");
    sgMap.put("吕布", "貂蝉");
    HashMap<String, String> sdMap = new HashMap<>();
    sdMap.put("郭靖", "黄蓉");
    sdMap.put("杨过", "小龙女");
    HashMap<String, String> xaMap = new HashMap<>();
    xaMap.put("令狐冲", "任盈盈");
    xaMap.put("林平之", "岳灵珊");

    ArrayList<HashMap<String, String>> maxList = new ArrayList<>();
    maxList.add(sgMap);
    maxList.add(sdMap);
    maxList.add(xaMap);
    for (HashMap<String, String> minMap : maxList) {
        Set<Map.Entry<String, String>> entries = minMap.entrySet();
        for (Map.Entry<String, String> entry : entries) {
            String key = entry.getKey();
            String value = entry.getValue();
            System.out.println(key+"------"+value);
        }
        System.out.println();
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值