瞒天过海之Hashset存入相同对象

本文介绍了一个学生类的设计,该类包含年龄和姓名两个属性,并重写了hashCode和equals方法。通过一个测试类演示了当修改对象属性后,原有的hashcode不变导致的行为表现,包括集合中元素的增删特性。

学生类,定义两个属性并重写hashcode和equals

public class Student{
    int age;
    String name;

    public Student(int age, String name) {
        this.age = age;
        this.name = name;
    }
    
    @Override
    public String toString() {
        return "Student{" +
                "age=" + age +
                ", name='" + name + '\'' +
                '}';
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        Student student = (Student) o;
        return age == student.age &&
                Objects.equals(name, student.name);
    }

    @Override
    public int hashCode() {
        return Objects.hash(age, name);
    }
}

测试类开始进行漫天过海

public class StudentCollection {
    public static void main(String[] args) {
        Student s1 = new Student(12, "小明");
        Student s2 = new Student(11, "小红");
        HashSet set = new HashSet();
        set.add(s1);
        set.add(s2);
        s1.name = "小张";
        set.remove(s1);
        set.add(new Student(12,"小张"));
        System.out.println(set);


    }
}

结果:

在这里插入图片描述

解析:

当时存入s1的hashcode已经定义好,即使修改属性也不变,所以再进行填入新的元素时,比较hashcode时,由于比较的是s1的旧属性的Hashcode值,所以不会相等,就能存入新的值。之前remove无法删除也是这个原因。

### 如何在 Redis 中使用 HashSet 存储对象 Redis 的 `HashSet` 是一种高效的键值对存储结构,特别适用于存储具有多个属性的对象。通过将对象的各个字段作为 `HashSet` 的子字段存储,可以实现快速访问和更新。 #### 使用 Redis 的 HashSet 存储对象的最佳实践 1. **定义对象模型** 首先需要明确要存储的对象及其字段。假设有一个表示用户的对象,包含以下字段:`id`, `name`, 和 `email`。 2. **序列化与反序列化** 如果直接使用 Redis CLI 或者低级 API,则可以通过手动拼接键值对的方式存储;如果使用高级框架(如 Spring Data Redis),则可以选择合适的序列化器来简化开发过程[^3]。 3. **代码示例** 以下是基于 Java 和 Spring Boot 的示例,展示如何利用 `RedisTemplate` 将用户对象存储到 Redis 的 `HashSet` 中: ```java import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.redis.core.RedisTemplate; import org.springframework.stereotype.Service; @Service public class UserService { @Autowired private RedisTemplate<String, Object> redisTemplate; public void saveUser(String userId, String name, String email) { // 设置 hash key 和 field-value 对应关系 redisTemplate.opsForHash().put("user:" + userId, "name", name); redisTemplate.opsForHash().put("user:" + userId, "email", email); System.out.println("User saved successfully."); } public Map<Object, Object> getUser(String userId) { // 获取整个 hash 表的内容 return redisTemplate.opsForHash().entries("user:" + userId); } } ``` 此代码片段展示了如何保存和读取用户信息至 Redis 的 `HashSet` 结构中。每条记录都以 `"user:<userId>"` 为根键名,而具体的字段(如名字和邮箱地址)被当作该哈希表内的子项处理。 4. **命令行操作实例** 对于不依赖任何编程语言的情况,在纯 Redis 环境下也可以轻松完成样的任务。下面给出一个简单的例子说明怎样手工录入数据以及查询这些数据: ```bash # 添加新纪录 HSET user:1001 name "Alice" HSET user:1001 email "alice@example.com" # 查看某一条记录的所有详情 HGETALL user:1001 # 更新某个特定字段 HSET user:1001 email "new.alice@example.com" # 删除整条记录或者部分字段 HDEL user:1001 email ``` 以上步骤涵盖了基本 CRUD 功能,并且能够满足大多数实际应用场景的要求[^4]。 --- ### 性能考量与其他建议 当涉及大规模并发写入时,需注意合理设计过期策略以免堆积过多无用数据占用内存资源。另外还可以考虑压缩算法减少空间消耗等问题[^1]。
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

布丁味

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值