Map表查找

文章目录


概念

Map 是 Java 中用于存储键值对的接口,它允许我们通过键来快速查找对应的值。在实际应用中,Map 提供了一种非常便捷的方式来组织和访问数据,常用于表示映射关系、计数、缓存等场景。

Map

Map体现的结构是一个多行两列的表格,其中左列称为key,右列称为value.

  • Map总是成对保存数据,并且总是根据key获取对应的value.因此我们可以将查询的条件作 为key查询对应的结果作为value保存到Map中.
  • Map有一个要求:key不允许重复(equals比较的结果)
    java.util.Map接口,是所有Map的顶级接口,规定了Map的相关功能.
    常用实现类:
  • java.util.HashMap:称为散列表,使用散列算法实现的Map,当今查询速度最快的数据结构.
  • java.util.TreeMap:使用二叉树实现的Map
java 复制代码
package map;

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

/**
 * java.util.Map接口  查找表
 * Map体现的结构像是一个多行两列的表格,其中左列称为key,右列称为value
 * Map总是成对儿(key-value键值对)保存数据,并且总是根据key获取其对应的value
 *  * 常用实现类:
 * java.util.HashMap:称为散列表,使用散列算法实现的Map,当今查询速度最快的
 *                   数据结构。
 */
public class MapDemo {
    public static void main(String[] args) {
        Map<String,Integer> map = new HashMap<>();
        /*
            V put(K k,V v)
            将给定的键值对儿存入Map
            Map有一个要求,即:Key不允许重复(Key的equals比较)
            因此如果使用重复的key存入value,则是替换value操作,此时put方法
            的返回值就是被替换的value。否则返回值为null。
         */
        /*
            注意,如果value的类型是包装类,切记不要用基本类型接收返回值,
            避免因为自动拆箱导致的空指针
         */
        Integer value = map.put("语文",99);
        System.out.println(value);//null
        map.put("数学",98);
        map.put("英语",97);
        map.put("物理",96);
        map.put("化学",98);
        System.out.println(map);

        value = map.put("物理",66);
        System.out.println(value);//96,物理被替换的值
        System.out.println(map);


        /*
            V get(Object key)
            根据给定的key获取对应的value。若给定的key不存在则返回值为null
         */
        value = map.get("语文");
        System.out.println("语文:"+value);

        value = map.get("体育");
        System.out.println("体育:"+value);//null

        int size = map.size();
        System.out.println("size:"+size);
        /*
            V remove(Object key)
            删除给定的key所对应的键值对,返回值为这个key对应的value
         */
        value = map.remove("语文");
        System.out.println(map);
        System.out.println(value);

        /*
            boolean containsKey(Object key)
            判断当前Map是否包含给定的key
            boolean containsValue(Object value)
            判断当前Map是否包含给定的value
         */
        boolean ck = map.containsKey("英语");
        System.out.println("包含key:"+ck);
        boolean cv = map.containsValue(97);
        System.out.println("包含value:"+cv);
    }
}

Map的遍历

Map支持三种遍历方式:

  • 遍历所有的key
  • 遍历所有的键值对
  • 遍历所有的value(相对不常用)
java 复制代码
package map;

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

/**
 - Map的遍历
 - Map提供了三种遍历方式
 - 1:遍历所有的key
 - 2:遍历每一组键值对
 - 3:遍历所有的value(不常用)
 */
public class MapDemo2 {
    public static void main(String[] args) {
        Map<String,Integer> map = new HashMap<>();
        map.put("语文",99);
        map.put("数学",98);
        map.put("英语",97);
        map.put("物理",96);
        map.put("化学",98);
        System.out.println(map);
        /*
            遍历所有的key
            Set keySet()
            将当前Map中所有的key以一个Set集合形式返回。遍历该集合就等同于
            遍历了所有的key
         */
        Set<String> keySet = map.keySet();
        for(String key : keySet){
            System.out.println("key:"+key);
        }

        /*
            遍历每一组键值对
            Set<Entry> entrySet()
            将当前Map中每一组键值对以一个Entry实例形式存入Set集合后返回。
            java.util.Map.Entry
            Entry的每一个实例用于表示Map中的一组键值对,其中有两个常用方法:
            getKey()和getValue()
         */
        Set<Map.Entry<String,Integer>> entrySet = map.entrySet();
        for(Map.Entry<String,Integer> e : entrySet){
            String key = e.getKey();
            Integer value = e.getValue();
            System.out.println(key+":"+value);
        }
        /*
            JDK8之后集合框架支持了使用lambda表达式遍历。因此Map和Collection都
            提供了foreach方法,通过lambda表达式遍历元素。
         */
        map.forEach(
             (k,v)-> System.out.println(k+":"+v)
        );


        /*
            遍历所有的value
            Collection values()
            将当前Map中所有的value以一个集合形式返回
         */
        Collection<Integer> values = map.values();
//        for(Integer i : values){
//            System.out.println("value:"+i);
//        }
        /*
            集合在使用foreach遍历时并不要求过程中不能通过集合的方法增删元素。
            而之前的迭代器则有此要求,否则可能在遍历过程中抛出异常。
         */
        values.forEach(
                i -> System.out.println("value:"+i)
        );
    }
}

常见的 Map 实现类

Java 提供了多种 Map 的实现类,每种实现类都有其特点和适用场景。以下是其中一些常见的 Map 实现类:

1.HashMap:

基于哈希表实现,具有快速的查找性能,但不保证顺序。

  • 特点:基于哈希表实现,具有快速的查找性能。
  • 适用场景:适用于大多数情况下的键值对存储和检索,不关心顺序。
  • 注意事项:允许键和值为null,不同步,不保证遍历顺序。
java 复制代码
Map<String, Integer> hashMap = new HashMap<>();
hashMap.put("Alice", 25);
hashMap.put("Bob", 30);
hashMap.put("Cathy", 28);

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

在这个例子中,我们使用HashMap存储了人名和对应的年龄,HashMap提供了快速的查找性能,适用于一般的键值对存储和检索场景。

2.TreeMap:

基于红黑树实现,可以按照键的自然顺序或者自定义顺序进行排序。

  • 特点:基于红黑树实现,可以按照键的自然顺序或者自定义顺序进行排序。
  • 适用场景:需要按照键的顺序进行遍历或查找的场景。
  • 注意事项:不允许键为null,但值可以为null;性能比HashMap略低;提供了一些额外的操作(如firstKey、lastKey等)。
java 复制代码
Map<String, Integer> treeMap = new TreeMap<>();
treeMap.put("Apple", 10);
treeMap.put("Banana", 5);
treeMap.put("Orange", 8);

// 遍历TreeMap
for (String key : treeMap.keySet()) {
    System.out.println(key + ": " + treeMap.get(key));
}

在上面的示例中,我们使用TreeMap按照水果名称的字典顺序进行存储,适用于需要按照键的顺序进行遍历或查找的场景。

3.LinkedHashMap:

基于哈希表和双向链表实现,保持插入顺序或者访问顺序。

  • 特点:基于哈希表和双向链表实现,可以保持插入顺序或者访问顺序(LRU缓存)。
  • 适用场景:需要保持插入顺序或访问顺序的场景,例如LRU缓存。
  • 注意事项:允许键和值为null;遍历时性能略低于HashMap。
java 复制代码
Map<String, String> linkedHashMap = new LinkedHashMap<>();
linkedHashMap.put("Monday", "Work");
linkedHashMap.put("Tuesday", "Gym");
linkedHashMap.put("Wednesday", "Meeting");

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

在这个例子中,我们使用LinkedHashMap存储了星期和对应的活动,LinkedHashMap可以保持插入顺序,适用于需要保持插入顺序或访问顺序的场景。

4.ConcurrentHashMap:

线程安全的 HashMap 实现,适用于并发环境下的操作。

  • 特点:线程安全的HashMap实现,使用分段锁来提高并发性能。
  • 适用场景:并发环境下对Map进行操作的场景。
  • 注意事项:允许一定程度的并发更新,迭代器是弱一致性的;允许null值,但不允许null键。
java 复制代码
Map<String, Integer> concurrentHashMap = new ConcurrentHashMap<>();
concurrentHashMap.put("Java", 10);
concurrentHashMap.put("Python", 8);
concurrentHashMap.put("C++", 6);

// 遍历ConcurrentHashMap
concurrentHashMap.forEach((key, value) -> System.out.println(key + ": " + value));

在这个示例中,我们使用ConcurrentHashMap在并发环境下安全地存储和访问键值对,适用于需要在并发环境下进行操作的场景。

5.EnumMap:

键为枚举类型的特殊 Map 实现。

  • 特点:键为枚举类型的特殊Map实现。
  • 适用场景:适用于键是枚举类型的情况,提供了高效的实现。
  • 注意事项:不允许null键,但允许null值;内部以数组形式存储,性能较高。
java 复制代码
enum Day { MONDAY, TUESDAY, WEDNESDAY }

Map<Day, String> enumMap = new EnumMap<>(Day.class);
enumMap.put(Day.MONDAY, "First day of the week");
enumMap.put(Day.TUESDAY, "Second day of the week");

// 遍历EnumMap
for (Map.Entry<Day, String> entry : enumMap.entrySet()) {
    System.out.println(entry.getKey() + ": " + entry.getValue());
}

在这个例子中,我们使用EnumMap来存储一周的工作日和对应的描述,EnumMap适用于键是枚举类型的情况,并且提供了高效的实现。

总结

java.util.Map 查找表

特点:体现的结构是一个多行两列的表格,其中左列称为key,右列称为value。

Map中的key不允许重复。判定重复的标准是根据key的equals方法判定的。

常用的实现类:java.util.HashMap 散列表

使用场景和注意事项

  • 当需要快速查找键值对,并不关心顺序时,可以选择使用 HashMap。

  • 需要按照键的顺序进行遍历或查找时,可以选择使用 TreeMap 或 LinkedHashMap。

  • 在并发环境下进行操作时,应选择 ConcurrentHashMap 来确保线程安全。

    在使用 Map 时,需要注意以下几点:

  • 键和值都可以为 null,但需要注意空指针异常的情况。

  • 尽量避免频繁的扩容操作,可以在初始化时指定初始容量和负载因子来提高性能。

常用方法:

V put(K k,V v):向Map中添加一组键值对,使用重复的key存入新的value时,那么就是替换value操作。此时put方法 返回值为被替换的value。否则返回值为null。

V get(K k):根据给定的key获取对应的value。如果给定的key不存在则返回值为null

V remove(K k):根据给定key从Map中删除对应的键值对,返回值为该key对应的value。

int size():返回当前Map中的元素个数

void clear():清空Map

boolean containsKey(Object key):判断当前的Map是否包含给定的key

boolean containsValue(Object value):判断当前Map是否包含给定的value

Set keySet():遍历key使用的方法,将当前Map中所有的key以一个Set集合形式返回

Set entrySet():遍历每一组键值对的方法,将当前Map中每一组键值对(Entry实例)以一个Set集合形式返回

Collection values():遍历所有value使用的方法,将当前Map中所有的value以一个集合形式返回

forEach():基于lambda表达式遍历Map

相关推荐
Willliam_william17 分钟前
SystemC学习(1)— SystemC安装与HelloWorld
学习
程序员-珍18 分钟前
使用openapi生成前端请求文件报错 ‘Token “Integer“ does not exist.‘
java·前端·spring boot·后端·restful·个人开发
sealaugh3222 分钟前
aws(学习笔记第一课) AWS CLI,创建ec2 server以及drawio进行aws画图
笔记·学习·aws
布丁不叮早起枣祈22 分钟前
10.5学习
学习
弱冠少年25 分钟前
websockets库使用(基于Python)
开发语言·python·numpy
长天一色26 分钟前
C语言日志类库 zlog 使用指南(第五章 配置文件)
c语言·开发语言
向上的车轮31 分钟前
Django学习笔记五:templates使用详解
笔记·学习·django
一般清意味……38 分钟前
快速上手C语言【上】(非常详细!!!)
c语言·开发语言
卑微求AC38 分钟前
(C语言贪吃蛇)16.贪吃蛇食物位置随机(完结撒花)
linux·c语言·开发语言·嵌入式·c语言贪吃蛇
2401_8572979144 分钟前
招联金融2025校招内推
java·前端·算法·金融·求职招聘