五、Java集合类(三)Map

    xiaoxiao2022-07-12  144

    今天的博客主题

          基础篇 --》常用类 --》Java集合类(三)Map


    Map

     

    public interface Map<K,V> {}

    Map直接就是一个接口,已经约定KV结构的存储。

    Map也是一个集合和Collection是一个级别的。

    Map集合是双列的,键值对的方式存在的。

    Map的体系结构大概是这样子的。

    特点

    Map属于是一个映射,是无序的。以键值对的形式添加元素。键不能重复,值可以重复。HashMap只允许一条记录的键为NULL。每个键只能映射一个值。插入顺序和访问顺序无法保证

    Map只是一个接口,具体实现还得看实现类是怎么来实现的。


    HashMap

     

    public class HashMap<K,V> extends AbstractMap<K,V> implements Map<K,V>, Cloneable, Serializable {}

    HashMap继承AbstractMap类,实现了Map、Cloneable、Serializable接口

    AbstractMap实现了Map里的一系列方法。

    特点:

    既然是Map实现类,继承AbstractMap,那Map的特点HashMap是都有的。线程不安全

    HashMap是基于哈希表的Map接口实现的,而哈希表的作用就是来保证键是唯一的。

    如果要指定HashMap的Key(也就是键)一定要确保重写了equals()和hashCode()两个方法。

     

    核心方法(常用API)

     

    public static void main(String[] args) { // 创建一个HashMap集合。可以指定集合存放的键值类型 HashMap hashMap = new HashMap(); HashMap<String, Object> hashMapO = new HashMap(); HashMap<String, String> hashMapS = new HashMap(); // 往集合添加元素。键不可重复,重复会覆盖,值可重复 hashMap.put("1","a"); hashMap.put("1","b"); hashMap.put("2","c"); hashMap.put("3","d"); hashMap.put("4","d"); System.out.println(hashMap); // {1=b, 2=c, 3=d, 4=d} HashMap hashMap2 = new HashMap(); hashMap2.put("5","a"); // 往集合添加一个集合,相同键的值会被覆盖 hashMap.putAll(hashMap2); System.out.println(hashMap); // {1=b, 2=c, 3=d, 4=d, 5=a} // 获取集合长度 int size = hashMap.size(); System.out.println(size); // 5 // 验证集合是否为空 boolean empty = hashMap.isEmpty(); System.out.println(empty); // false // 通过指定键K获取对应值V Object o = hashMap.get("2"); System.out.println(o); // c // 验证集合是否包含指定的键K boolean b = hashMap.containsKey("2"); System.out.println(b); // true // 验证集合是否包含指定的值V boolean b1 = hashMap.containsValue("a"); System.out.println(b1); // true // 移除指定键 hashMap.remove("3"); System.out.println(hashMap); // {1=b, 2=c, 4=d, 5=a} // 获取集合里所有的键K Set set = hashMap.keySet(); System.out.println(set); // [1, 2, 4, 5] // 获取集合里所有的值V Collection values = hashMap.values(); System.out.println(values); // [b, c, d, a] // 将集合指定键K的指定的旧值替换为新的值,如果指定的旧值和集合内的旧值不一致就不会替换 hashMap.replace("5", "a", "e"); System.out.println(hashMap); // {1=b, 2=c, 4=d, 5=e} // 将集合指定键K的值替换为指定的值V,没限制,直接就替换了 hashMap.replace("5", "f"); System.out.println(hashMap); // {1=b, 2=c, 4=d, 5=f} // 清空集合 hashMap.clear(); System.out.println(hashMap); // {} }

    LinkedHashMap

    public class LinkedHashMap<K,V> extends HashMap<K,V> implements Map<K,V>{}

    LinkedHashMap继承了HashMap,实现了Map接口

    LinkedHashMap是HashMap的子类,自然LinkedHashMap也就继承了HashMap中所有非私有的方法。

    底层数据结构是数组加链表,可以认为他是HashMap和LinkedList的合体。

    特点

    有序的(可以这么认为它的出现是解决Map集合无序的问题)可指定排序方式

    核心方法(常用API)

    既然继承与HashMap,那HashMap只要不是私有的方法,那LinkedHashMap是都有的。

     

    Hashtable

     

    public class Hashtable<K,V> extends Dictionary<K,V> implements Map<K,V>, Cloneable, java.io.Serializable {}

    Hashtable继承Dictionary,实现Map、Cloneable、Serializable接口。

    和HashMap类似,都是KV结构存储的。

    就不着重介绍了,其常用的API也都相似。

     

    TreeMap

     

    public class TreeMap<K,V> extends AbstractMap<K,V> implements NavigableMap<K,V>, Cloneable, java.io.Serializable{}

    TreeMap继承AbstractMap,实现NavigableMap、Cloneable、Serializable接口。

    TreeMap是Map的实现类。

    TreeMap继承AbstractMap,是一个Map也就是一个KV结构集合

    底层数据结构是红黑树来实现的

    特点

    有序的K V集合支持排序(自然排序,比较器排序)

    核心方法(常用API)

     

    public static void main(String[] args) { // 创建一个TreeMap集合 TreeMap treeMap = new TreeMap(); // 往集合添加键值。有序的 会按照键来排序 treeMap.put("2","a"); treeMap.put("4","b"); treeMap.put("3","c"); treeMap.put("1","d"); System.out.println(treeMap); // {1=d, 2=a, 3=c, 4=b} HashMap hashMap = new HashMap(); hashMap.put("5","f"); hashMap.put("0","0"); // 往集合添加一个map集合 treeMap.putAll(hashMap); System.out.println(treeMap); // {0=0, 1=d, 2=a, 3=c, 4=b, 5=f} // 获取集合长度 int size = treeMap.size(); System.out.println(size); // 6 // 验证集合是否为空 boolean empty = treeMap.isEmpty(); System.out.println(empty); // false // 获取集合指定键K的值V Object o = treeMap.get("2"); System.out.println(o); // a // 验证集合是否包含指定键K boolean b = treeMap.containsKey("3"); System.out.println(b); // true // 验证集合是否包含指定值V boolean b1 = treeMap.containsValue("b"); System.out.println(b1); // true // 获取集合第一个键K Object o1 = treeMap.firstKey(); System.out.println(o1); // 0 // 获取集合最后一个键K Object o2 = treeMap.lastKey(); System.out.println(o2); // 5 // 移除指定键的值,并返回这个值 Object remove = treeMap.remove("1"); System.out.println(remove); // d // 获取集合第一个KV结构元素 Map.Entry entry = treeMap.firstEntry(); System.out.println(entry); // 0=0 // 获取集合最一个KV结构元素 Map.Entry entry1 = treeMap.lastEntry(); System.out.println(entry1); // 5=f // 将集合指定键K的指定值V进行替换,如果指定的值与集合内的值不一致,则不替换 treeMap.replace("0","0","1"); System.out.println(treeMap); // {0=1, 2=a, 3=c, 4=b, 5=f} // 将集合指定键K的指定值V进行替换,直接替换 treeMap.replace("0","2"); System.out.println(treeMap); // {0=2, 2=a, 3=c, 4=b, 5=f} // 清空集合 treeMap.clear(); System.out.println(treeMap); // {} }

    TreeMap同TreeSet一样有一个比较坑的地方。

    就是在声明Map集合时,指定的键类型没有实现Comparable接口,重写compareTo()方法。那么同样会出现异常。

    怎么解决呢?和TreeSet的解决方法一样。

     

    总结

    Map是键值对映射的接口

    HashMap底层是通过散列表实现的,是比较常用的,Key是通过hashCode值来存储数据的。可直接根据K获取V,访问速度很快。只允许一个K为null,V可以多个null。线程不安全,效率高。

    Hashtable与HashMap类似,唯一不同的就是Hashtable的K和V都不能为null。写入速度慢。线程安全的,效率低。

    TreeMap底层是通过红黑树实现的,能够把进行存储的数据按照K进行排序,默认是按升序排序,也可以指定排序的比较器。

    TreeMap不允许K为null。线程不安全,效率高。遍历时得到记录是排过序的。

    LinkedHashMap底层是通过链表实现的,有序的map集合,在插入值的时候可以自定义排序方式。key和value都允许为空。线程不安全。

     

    还是之前说的那句话,集合类这几篇文章只是对集合有个认知。如想深入了解,关注我。看源码篇》。。


    纸上得来终觉浅

    更深入的理解它才会得到它的心❤

    最新回复(0)