Java-Map

1 Map集合的介绍

  • java.util.Map<K,V> 集合,里面保存的数据是成对存在的,称之为双列集合。存储的数据,我们称为键值对。 之前所学的Collection集合中元素单个单个存在的,称为单列集合

2 特点

  • Map<K,V> K:键的数据类型;V:值的数据类型

  • 特点 :

    • 键不能重复,值可以重复

    • 键和值是 一 一 对应的,通过键可以找到对应的值

    • (键 + 值) 一起是一个整体 我们称之为“键值对” 或者 “键值对对象”,在Java中叫做“Entry对象”

  • 使用场景

    • 凡是要表示一一对应的数据时就可以Map集合

      • 举例 : 学生的学号和姓名 --- (itheima001 小智)

      • 举例 : 夫妻的关系 ---- (王宝强 马蓉 ) (谢霆锋 张柏芝)

3 常用实现类

  • HashMap:

    • 此前的HashSet底层实现就是HashMap完成的,HashSet保存的元素其实就是HashMap集合中保存的键,底层结构是哈希表结构,具有键唯一,无序,特点。

  • LinkedHashMap:

    • 底层结构是有链表和哈希表结构,去重,有序

  • TreeMap:

    • 底层是有红黑树,去重,通过键排序

4 常用的方法

  • public V put(K key, V value): 把指定的键与指定的值添加到Map集合中。

  • public V remove(Object key): 把指定的键 所对应的键值对元素 在Map集合中删除,返回被删除元素的值。

  • public V get(Object key) 根据指定的键,在Map集合中获取对应的值。

  • public Set<K> keySet(): 获取Map集合中所有的键,存储到Set集合中。

  • public boolean containKey(Object key):判断该集合中是否有此键。

基本操作示例

import java.util.*;

public class MapExample {
    public static void main(String[] args) {
        // 创建一个HashMap
        Map<String, Integer> map = new HashMap<>();

        // 添加键值对
        map.put("apple", 5);
        map.put("banana", 10);
        map.put("orange", 8);

        // 获取键对应的值
        int numberOfApples = map.get("apple");
        System.out.println("Number of apples: " + numberOfApples);

        // 遍历Map
        for (Map.Entry<String, Integer> entry : map.entrySet()) {
            System.out.println("Key: " + entry.getKey() + ", Value: " + entry.getValue());
        }

        // 检查是否包含某个键或值
        if (map.containsKey("banana")) {
            System.out.println("Map contains key 'banana'");
        }

        if (map.containsValue(8)) {
            System.out.println("Map contains value '8'");
        }

        // 删除键值对
        map.remove("orange");
        System.out.println("After removing 'orange', map size: " + map.size());
    }
}

5 Map集合的遍历

1. 使用 keySet() 遍历键和值

可以通过 MapkeySet() 方法获取所有的键,然后使用这些键来获取对应的值。

Map<String, Integer> map = new HashMap<>();
map.put("apple", 5);
map.put("banana", 10);
map.put("orange", 8);

for (String key : map.keySet()) {
    Integer value = map.get(key);
    System.out.println("Key: " + key + ", Value: " + value);
}

2. 使用 entrySet() 遍历键值对

通过 entrySet() 方法可以获取 Map 中所有的键值对,然后对每个键值对进行操作。

for (Map.Entry<String, Integer> entry : map.entrySet()) {
    String key = entry.getKey();
    Integer value = entry.getValue();
    System.out.println("Key: " + key + ", Value: " + value);
}

3. 使用 forEach() 方法(Java 8+)

如果你使用的是Java 8及更高版本,可以使用 forEach() 方法结合 Lambda 表达式来遍历 Map

map.forEach((key, value) -> {
    System.out.println("Key: " + key + ", Value: " + value);
});

4. 遍历值集合

如果你只关心 Map 中的值,可以直接遍历值集合。

for (Integer value : map.values()) {
    System.out.println("Value: " + value);
}

6 HashMap

HashMap 是Java中最常用的 Map 实现之一,它基于哈希表实现,提供了快速的插入、删除和查找操作。以下是关于 HashMap 的一些重要特点和使用注意事项:

特点和用法

  1. 基于哈希表

    • HashMap 内部使用哈希表来存储键值对,每个键值对通过计算哈希码存储在数组的某个位置。
    • 插入、删除、查找操作的平均时间复杂度为 O(1),在理想情况下可以是常数时间。
  2. 键的唯一性

    • 每个键在 HashMap 中是唯一的,如果插入具有相同键的新值,则会覆盖旧值。
  3. 允许键值为 null

    • HashMap 允许键和值都为 null,但只能有一个键为 null
  4. 不保证顺序

    • HashMap 不保证存储键值对的顺序,即使遍历时看起来像有序,也不应依赖此顺序。
  5. 举例
    import java.util.*;
    
    public class HashMapExample {
        public static void main(String[] args) {
            // 创建一个HashMap
            Map<String, Integer> hashMap = new HashMap<>();
    
            // 添加键值对
            hashMap.put("apple", 10);
            hashMap.put("banana", 20);
            hashMap.put("orange", 15);
    
            // 获取值
            System.out.println("Number of apples: " + hashMap.get("apple"));
    
            // 遍历HashMap
            for (Map.Entry<String, Integer> entry : hashMap.entrySet()) {
                System.out.println("Key: " + entry.getKey() + ", Value: " + entry.getValue());
            }
    
            // 删除键值对
            hashMap.remove("banana");
            System.out.println("After removing 'banana', HashMap: " + hashMap);
        }
    }
    

    7 LinkedHashMap

LinkedHashMap 是 Java 中的一种特殊类型的 Map 实现,它继承自 HashMap,在 HashMap 的基础上增加了对插入顺序或者访问顺序的维护。

特点和用法

  1. 保持顺序

    • LinkedHashMap 可以维护键值对的插入顺序或者访问顺序(最近最少使用,LRU)。插入顺序指的是键值对被添加到 Map 中的顺序;访问顺序指的是在使用 get 方法获取键值对时,该键值对被认为是最近被访问的,从而放到链表的末尾。
    • 可以通过构造函数选择保持插入顺序还是访问顺序。
  2. 线程不安全

    • 与 HashMap 类似,LinkedHashMap 也不是线程安全的。如果需要在多线程环境中使用,应该考虑使用 ConcurrentHashMap 或者在使用时手动同步。
  3. 实现细节

    • LinkedHashMap 使用双向链表维护插入顺序或访问顺序。这个链表负责连接哈希桶中的所有条目(Entry),并在迭代时提供预期的顺序。
    • 如果指定了访问顺序,则每次调用 get 方法时,相关的条目会被移到链表的末尾,这样最近访问的元素会被保持在最后。
    • 举例
      import java.util.*;
      
      public class LinkedHashMapExample {
          public static void main(String[] args) {
              // 创建一个LinkedHashMap,按插入顺序排序
              Map<String, Integer> linkedHashMap = new LinkedHashMap<>();
      
              // 添加键值对
              linkedHashMap.put("apple", 10);
              linkedHashMap.put("banana", 20);
              linkedHashMap.put("orange", 15);
      
              // 输出顺序与插入顺序一致
              System.out.println("LinkedHashMap entries:");
              for (Map.Entry<String, Integer> entry : linkedHashMap.entrySet()) {
                  System.out.println("Key: " + entry.getKey() + ", Value: " + entry.getValue());
              }
      
              // 访问一次 "banana",此时 "banana" 被移到最后
              linkedHashMap.get("banana");
      
              // 再次输出,"banana" 现在在最后
              System.out.println("After accessing 'banana':");
              for (Map.Entry<String, Integer> entry : linkedHashMap.entrySet()) {
                  System.out.println("Key: " + entry.getKey() + ", Value: " + entry.getValue());
              }
          }
      }
      

      8 TreeMap集合

特点和用法

  1. 有序性

    • TreeMap 中的键值对根据键的自然顺序或者自定义的比较器进行排序。默认情况下,键会按照升序排列。
    • 可以在构造函数中传入一个比较器来自定义排序规则。
  2. 性能

    • TreeMap 提供了基于红黑树的实现,因此插入、删除和查找操作的时间复杂度为 O(log n),其中 n 是 TreeMap 中的元素个数。
    • 这使得 TreeMap 在元素数量较大或需要频繁的插入、删除操作时,性能比较稳定,而不像 HashMap 那样在特定情况下会有较差的性能。
  3. 不允许空键

    • TreeMap 不允许键为 null。因为红黑树是根据键来排序和存储的,如果键为 null,无法比较和存储,会导致 NullPointerException
  4. 举例
    import java.util.*;
    
    public class TreeMapExample {
        public static void main(String[] args) {
            // 创建一个 TreeMap,按键的自然顺序排序
            TreeMap<String, Integer> treeMap = new TreeMap<>();
    
            // 添加键值对
            treeMap.put("apple", 10);
            treeMap.put("banana", 20);
            treeMap.put("orange", 15);
    
            // 输出键值对,按键的升序输出
            System.out.println("TreeMap entries:");
            for (Map.Entry<String, Integer> entry : treeMap.entrySet()) {
                System.out.println("Key: " + entry.getKey() + ", Value: " + entry.getValue());
            }
    
            // 使用自定义比较器,按键的长度降序排序
            TreeMap<String, Integer> lengthComparatorMap = new TreeMap<>(Comparator.comparing(String::length).reversed());
            lengthComparatorMap.put("apple", 10);
            lengthComparatorMap.put("banana", 20);
            lengthComparatorMap.put("orange", 15);
    
            // 输出自定义比较器排序后的键值对
            System.out.println("Custom Comparator TreeMap entries:");
            for (Map.Entry<String, Integer> entry : lengthComparatorMap.entrySet()) {
                System.out.println("Key: " + entry.getKey() + ", Value: " + entry.getValue());
            }
        }
    }
    

  • 9
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值