Map<String,Object> map=new HashMap<String,Object>详解

本文深入解析了HashMap的数据结构,探讨了其工作原理,包括如何通过哈希算法确定存储位置,以及通过equals方法确定具体位置。同时,文章还介绍了HashMap的两个关键参数——初始容量和负载因子,它们对性能的影响,以及如何合理设置这些参数以优化性能。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Map是一个接口,即Interface Map<K,V>,其中K-key类型和V-value的类型

  它的每个元素包含一个key对象和一个value对象,且在这两个对象之间存在一种映射的对应关系,所有从Map集合中访问元素时,只有指定了key就可以找到对应的value,因此key必须是唯一的且不能重复,当key相同时,后面的value值会覆盖之前的value值。

Map定义的一些通用的方法

Map接口有很多实现类,如TreeMap,Hashtable,SortedMap,HashMap。

HashMap,即Class HashMap<K,V>,是基于哈希表的Map接口实现。

  此实现提供所有可选的映射操作,并允许空值和空键。这个类不保证地图的顺序,特别是它不保证该顺序会随着时间的推移保持不变。

(1)HashMap的数据结构

  在Java编程语言中,最基本的结构就是两种,一个是数组,另外一个是指针(引用),HashMap就是通过这两个数据结构进行实现。HashMap实际上是一个“链表散列”的数据结构,即数组和链表的结合体。HashMap底层就是一个数组结构,数组中的每一项又是一个链表。当新建一个HashMap的时候,就会初始化一个数组。

  HashMap在底层将key-value当成一个整体进行处理,这个整体就是一个Entry对象。HashMap底层采用一个Entry[]数组来保存所有的key-value对,当需要存储一个Entry对象时,会根据hash算法来决定器在数组中的存储位置,再根据equals方法决定其在该数组位置上的链表中的存储位置;当需要取出一个Entry时,也会根据hash算法找到其在数组中存储位置,再根据equals方法从该位置上的链表中取出该Entry。

(2)HashMap的两个影响其性能的参数:初始容量和负载因子。

  容量是在哈希表中桶的数量,初始容量是简单地在创建哈希表中的时间的能力。负载因子衡量的是一个散列表的空间的使用速度,负载因子越大表示散列表的装填程度越高,反之越小。当哈希表中的条目数超过加载因子和当前容量的乘积时,哈希表将被重新哈希(重建内部数据结构),以便哈希表具有大约两倍的桶数。作为一般规则,默认加载因子(0.75)在时间和空间成本之间提供了良好的权衡。较高的值会减少空间开销,但会增加查找成本(体现在HashMap类的大多数类操作中,包括get和put)。在设置其初始容量时,应考虑映射中的预期条目数及其加载因子,以便最小化重新散列操作的数量。如果初始容量大于最大条目数除以加载因子,则不会发生重新加载操作。

例子

Map<String,Object> map = new HashMap<String,Object>();//创建Map对象,Object是所有类型的父类
map.put("publish",publish);//存储key和value
map.put("status",status);
map.get("publish");//获取相应key的值

 

### RedisTemplate `opsForValue()` 方法详解 `RedisTemplate.opsForValue()` 是 Spring Data Redis 提供的一个方法,用于获取针对 Redis 中字符串类型的键值对操作接口。返回的对象是一个实现了 `ValueOperations<K, V>` 接口的实例[^2]。 #### ValueOperations 的功能 `ValueOperations<K, V>` 主要提供了对 Redis 字符串类型数据的操作能力。以下是其常用的方法及其说明: 1. **设置单个键值对** ```java operations.set(key, value); ``` 此方法会将指定的 key 设置为对应的 value 值[^1]。 2. **带过期时间的设置** ```java operations.set(key, value, timeout, TimeUnit.SECONDS); ``` 这种方式允许在存储的同时定义该键的有效期,单位可以是秒、毫秒等。 3. **批量设置多个键值对** ```java Map<String, String> map = new HashMap<>(); map.put("key1", "value1"); map.put("key2", "value2"); operations.multiSet(map); ``` 可以一次性设置多组键值对到 Redis 中。 4. **获取单个键的值** ```java String result = operations.get(key); ``` 返回对应 key 存储的 value 值,如果不存在则返回 null。 5. **增量操作** 对于数值型的数据支持自增或自减: ```java Long incrementResult = operations.increment(key, delta); Long decrementResult = operations.decrement(key, delta); ``` 上述两个方法分别实现加法和减法运算,并更新原值。 6. **追加字符串** 如果目标 key 已经存在,则会在原有基础上附加新的内容;否则创建新记录。 ```java Integer appendLength = operations.append(key, additionalText); ``` 7. **删除特定字段** 删除某个已存在的 key 所关联的内容。 ```java Boolean deleteStatus = operations.getOperations().delete(key); ``` 8. **判断是否存在某 Key** 判断当前数据库里是否有这个 key 记录。 ```java Boolean existsFlag = operations.getOperations().hasKey(key); ``` 9. **获取子字符串** 获取指定范围内的字符片段。 ```java String substring = operations.get(key, startOffset, endOffset); ``` 以上列举了一些常见的 API 调用形式,实际开发过程中可以根据业务需求灵活组合这些基础函数来完成复杂逻辑处理。 ### 使用场景分析 - 当应用程序需要缓存少量结构化信息时(比如用户的登录状态),可以通过 `ValueOperations` 将简单的对象序列化成 JSON 后保存至 Redis; - 实现计数器功能,利用原子性的增加/减少命令维护访问次数统计表; - 配合定时任务定期清理超时未使用的 session 数据等等[^3]。 ```java // 示例代码展示如何使用 ValueOperations 来管理用户在线状态 @Service public class UserService { @Autowired private RedisTemplate<String, Object> redisTemplate; public void login(String userId){ ValueOperations<String, Object> ops = redisTemplate.opsForValue(); ops.set(userId,"online",30,TimeUnit.MINUTES); // 用户上线并设定有效期为半小时 } public boolean isOnline(String userId){ ValueOperations<String, Object> ops = redisTemplate.opsForValue(); return ops.get(userId)!=null ? true:false; } } ```
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值