Java中的Map集合及其子类HashMap,LinkedHashMap,TreeMap,ConcurrentHashMap

一 .Map
public interface Map
将键映射到值的对象。一个映射不能包含重复的键;每个键最多只能映射到一个值。此接口哦取代了Dictionary类,后者完全是一个抽象类,而不是一个接口。
Map接口和Collection接口的区别

  • Map是双列的,而Collection是单列的
  • Map的键唯一,而Collection的子体系的Set是唯一的
  • Map集合的数据结构只针对键有效,跟值无关,而Collection集合的数据结构是针对元素有效

二 .下面先了解Map集合的基本功能,后面研究其常用的四个子类。
添加功能

  • V put(K key,V value)
      添加元素,也可以有替换功能,如果键是第一次存储,就直接存储元素,返回null。如果键已经存在,那么就用值把以前的值替换掉,返回以前的值

删除功能

  • void clear()
       移除所有的键值对元素

  • V remove(Object key)
      根据键删除键值对元素,并把值返回

获取功能

  • Set> entrySet()
      返回一个键值对的Set集合

  • V get(Object key)
      根据键获取值

  • Set keySet():获取集合中所有键的集合
      获取集合中所有键的集合

  • Collection values()
      获取集合中所有值的集合

判断功能

  • boolean containsKey(Object key)
      判断集合是否包含指定的键

  • boolean containsValue(Object value)
      判断集合是否包含制定的值

  • boolean isEmpty()
      判断集合是否为空

长度功能

  • int size()
      获取集合中的键值对的对数
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;

public class MyTest1 {
    public static void main(String[] args) {
        HashMap hashMap = new HashMap<>();
        hashMap.put("海绵宝宝",21);
        hashMap.put("章鱼哥",22);
        hashMap.put("派大星",23);
        hashMap.put("蟹老板",24);
        //当键已经存在时,再次存储就把旧值替换掉,返回以前的值
        Integer integer = hashMap.put("海绵宝宝", 25);
        //根据键删除键值对元素
        hashMap.remove(21);
        //判断集合是否包含指定的键
        hashMap.containsKey("派大星");
        //判断集合是否包含制定的值
        hashMap.containsValue(23);
        //返回一个键值对的Set集合
        Set entries = hashMap.entrySet();
        //根据键获取值
        hashMap.get("蟹老板");
        //返回集合中所有键的集合
        Set strings = hashMap.keySet();
        //获取集合中所有值的集合
        Collection values = hashMap.values();
        //获取集合中键值对的对数
        int size = hashMap.size();
        //清空所有的键值对元素
        hashMap.clear();
    }
}

三.Map集合的两种遍历方式
  方式一

import java.util.HashMap;
import java.util.Set;

public class MyTest2 {
    public static void main(String[] args) {
        HashMap hashMap = new HashMap<>();
        hashMap.put("海绵宝宝",21);
        hashMap.put("章鱼哥",22);
        hashMap.put("派大星",23);
        hashMap.put("蟹老板",24);
        Set set = hashMap.keySet();
        for (String key : set) {
            System.out.println(key+" "+hashMap.get(key));
        }
    }
}


  方式二

import java.util.HashMap;
import java.util.Map;
import java.util.Set;

public class MyTest3 {
    public static void main(String[] args) {
        HashMap hashMap = new HashMap<>();
        hashMap.put("海绵宝宝",21);
        hashMap.put("章鱼哥",22);
        hashMap.put("派大星",23);
        hashMap.put("蟹老板",24);
        Set> entries = hashMap.entrySet();
        for (Map.Entry entry : entries) {
            String key = entry.getKey();
            Integer value = entry.getValue();
            System.out.println(key+" "+value);
        }
    }
}

两个的运行结果为:

派大星 23
海绵宝宝 21
章鱼哥 22
蟹老板 24

四.Map接口下面常用的四个子类

  • HashMap
  • LinkedHashMap
  • TreeMap
  • ConcurrentHashMap

1.HashMap

  • 底层是散列表+红黑树。初始容量为16,加载因子为0.75,每次扩容两倍。
  • 允许nul值null键l,存储无序
  • 线程非同步
  • 散列表容量大于64且链表大于8时,转成红黑树
  • key的哈希值会与该值的高16位做异或操作,进一步增加随机性
  • 当散列表的元素大于容量 * 加载因子时,会在散列,每次扩容两倍
import java.util.HashMap;

public class MyTest5 {
    public static void main(String[] args) {
        HashMap hashMap = new HashMap<>();
        hashMap.put("海绵宝宝",21);
        hashMap.put("章鱼哥",22);
        hashMap.put("派大星",23);
        hashMap.put("蟹老板",24);
        hashMap.put("蟹老板",999);
        System.out.println(hashMap);
    }
}

运行结果为:

{派大星=23, 海绵宝宝=21, 章鱼哥=22, 蟹老板=999}

存取顺序不一致
2.LinkedHashMap

  • 底层数据结构是散列表+红黑树+双向链表
  • 键的数据结构是链表+哈希表,链保证键有序,哈希表保证键唯一
  • Map接口的哈希表和链接链表实现,具有可预知的迭代顺序。
  • 允许null值null键
  • 线程非同步
  • 提供插入顺序和访问顺序两种,访问顺序是符合LRU(最近最近未使用算法)的,一般用于扩展(默认是插入排序)。
  • 大多使用了HashMap的API,只不过在内部重写了某些方法,维护了双向链表
import java.util.LinkedHashMap;

public class MyTest4 {
    public static void main(String[] args) {
        LinkedHashMap linkedHashMap = new LinkedHashMap<>();
        linkedHashMap.put("郭杰瑞",34);
        linkedHashMap.put("角角",24);
        linkedHashMap.put("明明",27);
        linkedHashMap.put("木鱼水心",32);
        linkedHashMap.put("信誓旦旦",37);
        System.out.println(linkedHashMap);
    }
}

运行结果为:

{郭杰瑞=34, 角角=24, 明明=27, 木鱼水心=32, 信誓旦旦=37}

可以看出存取顺序一致

3.TreeMap

  • 底层是红黑树,保证了时间复杂度位log(n)
  • 可以对其进行排序,使用Comparable或者Comparator
  • 只要compare或者CompareTo认定该元素相等,那就相等
  • 线程非同步
  • 当自然排序(手动排序)元素不能为null

1.使用自然排序时,要求里面的元素实现了Comparable接口,重写了compareTo()方法。例如下面的一段代码,按照年龄对元素进行排序。

public class Student implements Comparable{
    private String name;
    private int age;
    public Student() {
    }

    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 int compareTo(Student s ) {
        int num = this.age - s.getAge();
        int num2=num==0?this.name.compareTo(s.name):num;
        return num2 ;
    }
}

import java.util.Map;
import java.util.Set;
import java.util.TreeMap;

public class MyTest1 {
    public static void main(String[] args) {
        TreeMap treeMap = new TreeMap<>();
        treeMap.put(new Student("章鱼哥",23),"海绵宝宝");
        treeMap.put(new Student("熊大",24),"熊出没");
        treeMap.put(new Student("叶修",23),"全职高手");
        //遍历方式二
        Set> entries = treeMap.entrySet();
        for (Map.Entry entry : entries) {
            Student key = entry.getKey();
            String value = entry.getValue();
            System.out.println(key.getAge()+" "+key.getName()+" "+value);
        }
    }
}

运行结果为:

23 叶修 全职高手
23 章鱼哥 海绵宝宝
24 熊大 熊出没

2.使用比较器排序

public class Student{
    private String name;
    private int age;
    public Student() {
    }

    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;
    }   
}
import java.util.Map;
import java.util.Set;
import java.util.TreeMap;

public class MyTest1 {
    public static void main(String[] args) {
        TreeMap treeMap = new TreeMap<>();
        treeMap.put(new Student("章鱼哥",23),"海绵宝宝");
        treeMap.put(new Student("熊大",24),"熊出没");
        treeMap.put(new Student("叶修",23),"全职高手");
        //遍历方式一
        Set> entries = treeMap.entrySet();
        for (Map.Entry entry : entries) {
            Student key = entry.getKey();
            String value = entry.getValue();
            System.out.println(key.getAge()+" "+key.getName()+" "+value);
        }
    }
}

运行结果为:

23 叶修 全职高手
17 天明 秦时明月
24 熊大 熊出没
23 章鱼哥 海绵宝宝

4.ConcurrentHashMap

  • 底层是散列表+红黑树,支持高并发操作
  • key和value都不能为空
  • 线程是安全的,利用CAS算法和部分操作上锁实现
  • get方法是通常是非阻塞,无锁的。重写Node类,通过volatile修饰next来实现每次获取都是最新设置的值
  • 在高并发环境下,统计数据(size等)是没有意义的,因为在下一时刻size值就变化了。

五.HashMap和Hashtable的区别

  • HashMap:线程不安全,效率高,允许null值null键。
  • HashTable:线程安全,效率低,不允许null值null键

六.集合之间的嵌套

  • HashMap嵌套HashMap
  • HashMap嵌套ArrayList
  • ArrayList嵌套HashMap

HashMap嵌套HashMap

import java.util.HashMap;
import java.util.Set;

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

            */

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

HashMap嵌套ArrayList

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Set;

public class MyTest2 {
    public static void main(String[] args) {
        /**
         *
         三国演义
             吕布
             周瑜
         笑傲江湖
            令狐冲
            林平之
         神雕侠侣
             郭靖
             杨过
         */

        //  HashMap 嵌套 ArrayList
        ArrayList sgList = new ArrayList<>();
        sgList.add("吕布");
        sgList.add("周瑜");
        ArrayList xaList = new ArrayList<>();
        xaList.add("令狐冲");
        xaList.add("林平之");
        ArrayList sdList = new ArrayList<>();
        sdList.add("郭靖");
        sdList.add("杨过");
        HashMap> hashMap = new HashMap<>();
        hashMap.put("三国演义",sgList);
        hashMap.put("笑傲江湖",xaList);
        hashMap.put("神雕侠侣",sdList);
        Set set = hashMap.keySet();
        for (String s : set) {
            System.out.println(s);
            ArrayList  list = hashMap.get(s);
            for (String s1 : list) {
                System.out.println("\t"+s1);
            }
        }
    }
}

ArrayList嵌套HashMap

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Set;

public class MyTest3 {
    public static void main(String[] args) {
        //周瑜-- - 小乔
        //吕布-- - 貂蝉
        //
        //郭靖-- - 黄蓉
        //杨过-- - 小龙女
        //
        //令狐冲-- - 任盈盈
        //林平之-- - 岳灵珊

        //ArrayList 嵌套 HashMap
        HashMap sgMap = new HashMap<>();
        sgMap.put("周瑜","小乔");
        sgMap.put("吕布","貂蝉");
        HashMap sdMap = new HashMap<>();
        sdMap.put("郭靖","黄蓉");
        sdMap.put("杨过","小龙女");
        HashMap xaMap = new HashMap<>();
        xaMap.put("令狐冲","任盈盈");
        xaMap.put("林平之","岳灵珊");
        ArrayList> maxList = new ArrayList<>();
        maxList.add(sgMap);
        maxList.add(sdMap);
        maxList.add(xaMap);
        for (HashMap map : maxList) {
            Set set = map.keySet();
            for (String s : set) {
                System.out.println(s+"---"+map.get(s));
            }
            System.out.println();
        }
    }
}

你可能感兴趣的:(Java中的Map集合及其子类HashMap,LinkedHashMap,TreeMap,ConcurrentHashMap)