使用可变对象作为Java Map的key,会带来潜在风险的一个例子

简介: 使用可变对象作为Java Map的key,会带来潜在风险的一个例子
package hashMap;
import java.util.HashMap;
import java.util.Map;
/* 
 * 可变对象是指创建后自身状态能改变的对象。换句话说,可变对象是该对象在创建后它的哈希值可能被改变。
在下面的代码中,对象MutableKey的键在创建时变量 i=10 j=20,哈希值是1291。
然后我们改变实例的变量值,该对象的键 i 和 j 从10和20分别改变成30和40。现在Key的哈希值已经变成1931。
显然,这个对象的键在创建后发生了改变。所以类MutableKey是可变的。
 */
class MutableKey {
  private int i;
  private int j;
  public MutableKey(int i, int j) {
    this.i = i;
    this.j = j;
  }
  public final int getI() {
    return i;
  }
  public final void setI(int i) {
    this.i = i;
  }
  public final int getJ() {
    return j;
  }
  public final void setJ(int j) {
    this.j = j;
  }
  @Override
  public int hashCode() {
    final int prime = 31;
    int result = 1;
    result = prime * result + i;
    result = prime * result + j;
    return result;
  }
  @Override
  public boolean equals(Object obj) {
    if (this == obj) {
      return true;
    }
    if (obj == null) {
      return false;
    }
    if (!(obj instanceof MutableKey)) {
      return false;
    }
    MutableKey other = (MutableKey) obj;
    if (i != other.i) {
      return false;
    }
    if (j != other.j) {
      return false;
    }
    return true;
  }
}
public class objectAsKey {
  private static void simulateObjectLost() {
    // HashMap
    Map<MutableKey, String> map = new HashMap<>();
    // Object created
    MutableKey key = new MutableKey(10, 20);
    // Insert entry.
    map.put(key, "Robin");
    // This line will print 'Robin'
    System.out.println(map.get(key));
    // Object State is changed after object creation.
    // i.e. Object hash code will be changed.
    key.setI(30);
    // This line will print null as Map would be unable to retrieve the entry.
    System.out.println(map.get(key));
  }
  public static void main(String[] args) {
    // Object created
    MutableKey key = new MutableKey(10, 20);
    System.out.println("Hash code: " + key.hashCode());
    // Object State is changed after object creation.
    key.setI(30);
    key.setJ(40);
    System.out.println("Hash code: " + key.hashCode());
    simulateObjectLost();
  }
}


相关文章
|
1天前
|
Java
Java一分钟之-类与对象:面向对象编程入门
【5月更文挑战第8天】本文为Java面向对象编程的入门指南,介绍了类与对象的基础概念、常见问题及规避策略。文章通过代码示例展示了如何定义类,包括访问修饰符的适当使用、构造器的设计以及方法的封装。同时,讨论了对象创建与使用时可能遇到的内存泄漏、空指针异常和数据不一致等问题,并提供了相应的解决建议。学习OOP需注重理论与实践相结合,不断编写和优化代码。
14 1
|
7天前
|
SQL Java 数据库连接
15:MyBatis对象关系与映射结构-Java Spring
15:MyBatis对象关系与映射结构-Java Spring
27 4
|
9天前
|
Java
java Map删除值为null的元素
java Map删除值为null的元素
|
9天前
|
Java fastjson
Java将Map转换为实体类
Java将Map转换为实体类
|
10天前
|
Java 编译器
【Java探索之旅】解密构造方法 对象初始化的关键一步
【Java探索之旅】解密构造方法 对象初始化的关键一步
16 1
|
10天前
|
Java
Java对象和类研究
Java对象和类研究
8 0
|
11天前
|
机器学习/深度学习 人工智能 算法
java对象的比较
java对象的比较
21 0
java对象的比较
|
11天前
|
Java
Java学习——类与对象(二)
Java学习——类与对象(二)
|
7月前
|
存储 Java
java集合框架------Map接口与实现类
java集合框架------Map接口与实现类
|
15天前
|
存储 安全 Java
[Java基础面试题] Map 接口相关
[Java基础面试题] Map 接口相关