Map接口的实现类HashMap、TreeMap和LinkedHashMap

169 阅读4分钟

Map接口

在Java中,Map是一种数据结构,它提供了将键映射到值的能力。它表示一个映射表,其中的元素是键值对。Map接口是Java Collections Framework中的一部分,并在Java中非常常用。

Map接口基础

  1. Map接口是一个泛型接口,它有两个泛型参数:键类型和值类型。

  2. Map中的元素是以键值对的形式存在的,键和值都可以是任何引用类型。

  3. Map中的键是唯一的,但值可以重复。

  4. Map中的元素没有顺序,因此不可以使用索引来访问元素,而必须使用键来访问元素。

  5. 常用的实现类有HashMap、TreeMap、LinkedHashMap等。

  6. HashMap是最常用的实现类之一,它是基于哈希表实现的,具有很高的插入和查询效率。但是,它的元素没有顺序。

  7. TreeMap是另一个常用的实现类,它是基于红黑树实现的,具有排序功能。但是,它的插入和查询效率相对较低。

  8. LinkedHashMap是HashMap的子类,它保留了元素插入的顺序,并提供了对元素的迭代访问。

  9. Map接口提供了许多有用的方法,例如put()、get()、containsKey()、containsValue()、remove()等。

  10. Map接口也提供了一些方法来遍历它的键、值或键值对,例如keySet()、values()、entrySet()等。

Map接口代码示例

创建一个HashMap,并向其中添加元素,以及如何使用键来访问值

import java.util.HashMap;  
import java.util.Map;  
  
public class MapExample {  
    public static void main(String[] args) {  
        Map<String, Integer> myMap = new HashMap<String, Integer>();  
        myMap.put("apple"1);  
        myMap.put("banana"2);  
        myMap.put("cherry"3);  
          
        System.out.println(myMap.get("apple")); // 输出:1  
        System.out.println(myMap.get("banana")); // 输出:2  
          
        if (myMap.containsKey("cherry")) {  
            System.out.println("myMap contains cherry"); // 输出:myMap contains cherry  
        }  
          
        if (myMap.containsValue(2)) {  
            System.out.println("myMap contains value 2"); // 输出:myMap contains value 2  
        }  
          
        myMap.remove("apple");  
          
        for (String key : myMap.keySet()) {  
            System.out.println(key + " -> " + myMap.get(key));  
        }  
        // 输出:  
        // cherry -> 3  
        // banana -> 2  
    }  
}

HashMap

HashMap是最常用的Map实现类之一,它使用哈希表来存储键值对。

主要特点

  1. 键和值都可以为null;
  2. 不保证元素的顺序;
  3. 迭代器遍历时,不保证元素的顺序;
  4. 基于哈希表实现,元素的存储和查找速度快。

HashMap代码实现

Map<String, Integer> map = new HashMap<>();  
map.put("one"1);  
map.put("two"2);  
map.put("three"3);  
  
// 遍历map  
for (Map.Entry<String, Integer> entry : map.entrySet()) {  
    System.out.println("Key = " + entry.getKey() + ", Value = " + entry.getValue());  
}

TreeMap

TreeMap是基于红黑树实现的Map,它可以对键进行排序,默认是按照键的自然顺序排序。

主要特点

  1. 键不能为null;
  2. 基于红黑树实现,元素的存储和查找速度较快;
  3. 按照键的自然顺序排序,或者使用Comparator进行排序;
  4. 迭代器遍历时,元素是按照键的顺序排列的。

TreeMap代码实现

Map<String, Integer> map = new TreeMap<>();  
map.put("one"1);  
map.put("two"2);  
map.put("three"3);  
  
// 遍历map  
for (Map.Entry<String, Integer> entry : map.entrySet()) {  
    System.out.println("Key = " + entry.getKey() + ", Value = " + entry.getValue());  
}  

LinkedHashMap

LinkedHashMap是HashMap的子类,它使用双向链表来维护元素的顺序。

主要特点:

  1. 保留元素插入的顺序;
  2. 遍历元素时,元素的顺序是按照插入顺序排列的;
  3. 迭代器遍历时,元素的顺序与插入顺序一致。

LinkedHashMap代码实现

Map<String, Integer> map = new LinkedHashMap<>();  
map.put("one"1);  
map.put("two"2);  
map.put("three"3);  
  
// 遍历map  
for (Map.Entry<String, Integer> entry : map.entrySet()) {  
    System.out.println("Key = " + entry.getKey() + ", Value = " + entry.getValue());  
}

优缺点

HashMap

HashMap基于哈希表实现,能够提供O(1)的时间复杂度的常数级别的访问和插入操作。它是非线程安全的,适合在单线程环境下使用。但由于哈希表是基于数组实现的,所以在扩容时需要重新计算哈希值,可能会导致性能下降。

TreeMap

TreeMap基于红黑树实现,能够提供O(log n)的时间复杂度的访问和插入操作,它可以保证元素有序。由于是基于树结构实现的,所以在大数据量的情况下性能比HashMap略差。但相对而言,TreeMap在数据量较少时,比如小于1000,它的性能是优于HashMap的。

LinkedHashMap

LinkedHashMap基于哈希表和链表实现,它既能够提供O(1)的时间复杂度的常数级别的访问和插入操作,又可以保证元素的顺序。它维护了一个双向链表,因此在迭代时能够保证元素的顺序。与HashMap相比,它需要维护链表结构,所以在性能方面比HashMap略差。

选择

需要根据具体的需求来选择适合的Map实现类。如果需要高效的插入和查询操作,且不需要保证元素的顺序,则选择HashMap。如果需要保证元素有序,则选择TreeMap。如果需要同时保证元素顺序和高效的插入和查询操作,则选择LinkedHashMap。