首页
学习
活动
专区
圈层
工具
发布

Java 中 Map 的实现:无序与有序的区别及应用

在 Java 中,Map 是一个非常常用的数据结构,它用于存储键值对(key-value pair)。

与 List 和 Set 不同,Map 存储的是一组“键”和“值”的映射关系。

比如,我们可以通过一个人的名字(键)来找到这个人的年龄(值)。

然而,Map 有不同的实现方式,根据存储数据的顺序,Map 可以分为“无序”和“有序”两大类。

一、无序的 Map

1.1 HashMap——最常用的无序 Map

HashMap 是 Java 中最常见的 Map 实现,它基于哈希表(hash table)实现。

HashMap 不保证元素的顺序,也就是说,插入元素的顺序与遍历顺序没有关系。每次打印出来的顺序可能都不一样。

HashMap的特点:

无序

HashMap中的元素没有顺序。

快速

由于哈希表的特性,HashMap 的查找速度非常快(接近 O(1))。

允许 null 键和 null 值

HashMap允许存储一个 null 键和多个 null 值。

示例:

import java.util.HashMap;

import java.util.Map;

publicclass HashMapExample {

  public static void main(String[] args) {

      Map<Integer, String> map = new HashMap<>();

      map.put(1, "One");

      map.put(3, "Three");

      map.put(2, "Two");

      map.put(5, "Five");

      map.put(4, "Four");

      // 输出的顺序不固定

      for (Map.Entry<Integer, String> entry : map.entrySet()) {

          System.out.println(entry.getKey() + ": " + entry.getValue());

      }

  }

}

输出(顺序可能不同):

1: One

2: Two

3: Three

4: Four

5: Five

1.2 无序 Map总结

优点

查找速度快,适合不关心顺序的场景。

缺点

无法控制元素的顺序。

二、有序的 Map

有序的 Map 保证了元素的顺序,通常有两种方式:按插入顺序排序,或者按键的自然顺序(或者指定的顺序)排序。

常用的有序 Map 有 LinkedHashMap 和 TreeMap。

2.1 LinkedHashMap——保持插入顺序

LinkedHashMap 是 HashMap 的一个变种,它除了具有 HashMap 的高效查找特性外,还维护了元素的插入顺序。也就是说,插入的顺序和遍历的顺序一致。

特点:

保持插入顺序

元素按照插入的顺序排列。

稍慢于HashMap

由于需要维护插入顺序,LinkedHashMap相比 HashMap 稍慢一些,但差别通常不大。

允许null键和null值

与 HashMap一样,LinkedHashMap 也允许 null 键和 null 值。

示例:

import java.util.LinkedHashMap;

import java.util.Map;

publicclass LinkedHashMapExample {

  public static void main(String[] args) {

      Map<Integer, String> map = new LinkedHashMap<>();

      map.put(1, "One");

      map.put(3, "Three");

      map.put(2, "Two");

      map.put(5, "Five");

      map.put(4, "Four");

      // 输出的顺序是插入顺序

      for (Map.Entry<Integer, String> entry : map.entrySet()) {

          System.out.println(entry.getKey() + ": " + entry.getValue());

      }

  }

}

输出

1: One

3: Three

2: Two

5: Five

4: Four

2.2 TreeMap——按照键的自然顺序排序

TreeMap 是一种基于红黑树的数据结构实现,它的特点是会自动根据键的大小进行排序。如果键实现了 Comparable 接口,TreeMap 会按键的自然顺序进行排序。如果需要按照自定义顺序排序,可以提供一个 Comparator 来定制排序规则。

特点:

按键排序

自动根据键的自然顺序或提供的比较器进行排序。

不允许null键

TreeMap不允许使用 null 作为键,虽然它允许 null 值。

适合需要排序的场景

如果我们需要频繁按顺序操作 Map,比如范围查询等,TreeMap 是一个不错的选择。

示例:

import java.util.Map;

import java.util.TreeMap;

publicclass TreeMapExample {

  public static void main(String[] args) {

      Map<Integer, String> map = new TreeMap<>();

      map.put(3, "Three");

      map.put(1, "One");

      map.put(2, "Two");

      map.put(5, "Five");

      map.put(4, "Four");

      // 按照键的自然顺序输出

      for (Map.Entry<Integer, String> entry : map.entrySet()) {

          System.out.println(entry.getKey() + ": " + entry.getValue());

      }

  }

}

输出

1: One

2: Two

3: Three

4: Four

5: Five

2.3 ConcurrentSkipListMap——线程安全的有序Map

ConcurrentSkipListMap 是一个线程安全的 Map 实现,它也按照键的顺序进行排序。ConcurrentSkipListMap 使用跳表(Skip List)实现,适用于并发场景。与 TreeMap 相似,它也支持按键的自然顺序或自定义顺序排序。

特点:

线程安全

适用于多线程环境。

按键排序

自动根据键的自然顺序或提供的比较器进行排序。

高并发性能

由于跳表的特点,它在多线程环境下表现较好。

示例:

import java.util.Map;

import java.util.concurrent.ConcurrentSkipListMap;

publicclass ConcurrentSkipListMapExample {

  public static void main(String[] args) {

      Map<Integer, String> map = new ConcurrentSkipListMap<>();

      map.put(3, "Three");

      map.put(1, "One");

      map.put(2, "Two");

      map.put(5, "Five");

      map.put(4, "Four");

      // 按照键的自然顺序输出

      for (Map.Entry<Integer, String> entry : map.entrySet()) {

          System.out.println(entry.getKey() + ": " + entry.getValue());

      }

  }

}

输出

1: One

2: Two

3: Three

4: Four

5: Five

三、最后总结

1、无序 Map(如 HashMap)

优点:查找速度快,适合不关心元素顺序的场景。

缺点:无法保证元素的遍历顺序。

2、有序 Map

LinkedHashMap:保持插入顺序,适合需要保持插入顺序的场景

TreeMap:按键排序,适合需要根据键的顺序排序的场景。

ConcurrentSkipListMap:线程安全的有序 Map,适用于多线程环境。

3、有序和无序的选择

如果我们不关心元素的顺序,只需要快速查找,选择 HashMap。

如果我们需要保持插入顺序,选择 LinkedHashMap。

如果我们需要按键的排序,选择 TreeMap。

如果我们需要线程安全的有序 Map,选择 ConcurrentSkipListMap。

理解这些 Map 的特点,我们就能够根据需求在项目中选择最合适的实现方式了。

  • 发表于:
  • 原文链接https://page.om.qq.com/page/ODbbTgMxY9ls5kpvWnQhmhrw0
  • 腾讯「腾讯云开发者社区」是腾讯内容开放平台帐号(企鹅号)传播渠道之一,根据《腾讯内容开放平台服务协议》转载发布内容。
  • 如有侵权,请联系 cloudcommunity@tencent.com 删除。
领券