HashMap存取过程中改变key值导致的内存泄露
来源:互联网 发布:淘宝给差评被砍死 编辑:程序博客网 时间:2024/06/09 14:22
HashMap是通过键值对的形式来存储数据的,把某个对象存入Map后,我们在外部把key的值修改,然后再通过这个新的key值从HashMap集合中获取元素,这时候可以取出原来的值吗?
我们通过一个测试示例来说明:
class User{private Integer uid;private String uname;public User(Integer uid, String uname) {this.uid = uid;this.uname = uname;}public Integer getUid() {return uid;}public void setUid(Integer uid) {this.uid = uid;}public String getUname() {return uname;}public void setUname(String uname) {this.uname = uname;}@Overridepublic int hashCode() {final int prime = 31;int result = 1;result = prime * result + ((uid == null) ? 0 : uid.hashCode());result = prime * result + ((uname == null) ? 0 : uname.hashCode());return result;}@Overridepublic boolean equals(Object obj) {if (this == obj)return true;if (obj == null)return false;if (getClass() != obj.getClass())return false;User other = (User) obj;if (uid == null) {if (other.uid != null)return false;} else if (!uid.equals(other.uid))return false;if (uname == null) {if (other.uname != null)return false;} else if (!uname.equals(other.uname))return false;return true;}}public class MapTest {public static void main(String[] args) {/*创建一个User对象*/User user = new User(1, "习近平");/*创建一个Map集合*/Map<User, String> maps = new HashMap<User, String>();/*往集合中添加数据【key为User对象,value为一个字符串】*/maps.put(user, "中国梦");/*打印user的hashCode()值*/System.out.println("user的hashCode值:" + user.hashCode());/*遍历获取key值,然后把key值改掉*/for (Entry<User, String> entry : maps.entrySet()){if (entry.getKey().getUname().equals("习近平")){entry.getKey().setUname("胡锦涛");}}/*再次打印user的hashCode值*/System.out.println("key值改变后,user的hashCode值:" + user.hashCode());/*通过迭代器获取key,然后通过key获取value值*/Iterator<User> it = maps.keySet().iterator();/*遍历获取value值*/while(it.hasNext()){User u = (User) it.next();System.out.println("user:" + maps.get(u));}}}
程序最终的输出结果为null !!!!
HashMap在存储元素时如果key值发生变化,hashCode值也会变化!
也就是说我们在使用HashMap存取的过程中,不要轻易改变key的值,如果改变了,就会导致取不出最初的value值,也就是说当初的那个value值留在了内存中,成为了垃圾,如果越积越多,最终就会导致内存泄露咯!!!!!
所以,当key值改变以后,user对象的hashCode值也发生了变化,从而导致取不出当初对应的那个value值了,其实这是可以改变的,我们可以重写hashCode()方法使得hashCode值不依赖于我们修改的属性!
如下修改【修改hashCode()方法使要更新的uname属性不参加hashCode的算法】:
class User{private Integer uid;private String uname;public User(Integer uid, String uname) {this.uid = uid;this.uname = uname;}public Integer getUid() {return uid;}public void setUid(Integer uid) {this.uid = uid;}public String getUname() {return uname;}public void setUname(String uname) {this.uname = uname;}@Overridepublic int hashCode() {final int prime = 31;int result = 1;result = prime * result + ((uid == null) ? 0 : uid.hashCode());//result = prime * result + ((uname == null) ? 0 : uname.hashCode());return result;}@Overridepublic boolean equals(Object obj) {if (this == obj)return true;if (obj == null)return false;if (getClass() != obj.getClass())return false;User other = (User) obj;if (uid == null) {if (other.uid != null)return false;} else if (!uid.equals(other.uid))return false;if (uname == null) {if (other.uname != null)return false;} else if (!uname.equals(other.uname))return false;return true;}}public class MapTest {public static void main(String[] args) {/*创建一个User对象*/User user = new User(1, "习近平");/*创建一个Map集合*/Map<User, String> maps = new HashMap<User, String>();/*往集合中添加数据【key为User对象,value为一个字符串】*/maps.put(user, "中国梦");/*打印user的hashCode()值*/System.out.println("user的hashCode值:" + user.hashCode());/*遍历获取key值,然后把key值改掉*/for (Entry<User, String> entry : maps.entrySet()){if (entry.getKey().getUname().equals("习近平")){entry.getKey().setUname("胡锦涛");}}/*再次打印user的hashCode值*/System.out.println("key值改变后,user的hashCode值:" + user.hashCode());/*通过迭代器获取key,然后通过key获取value值*/Iterator<User> it = maps.keySet().iterator();/*遍历获取value值*/while(it.hasNext()){User u = (User) it.next();System.out.println("user:" + maps.get(u));}}}
此时就可以取出user对象咯!!!!!
0 0
- HashMap存取过程中改变key值导致的内存泄露
- Volley中listener导致的内存泄露
- HashMap 中插入null key 的过程
- UIActionSheet关闭动画过程中调用delegate = nil 导致的内存泄露
- fork 导致的内存泄露
- Flex 中可能导致内存泄露的地方
- JNI接口中jstring导致内存泄露问题的解决
- Flex 中可能导致内存泄露的地方
- Android-Fragment中TextView.setFocusable(true)导致的内存泄露
- Android-Fragment中TextView.setFocusable(true)导致的内存泄露
- Android中Handler使用不当导致内存泄露的问题
- android开发中,可能会导致内存泄露的问题
- 【转】android开发中,可能会导致内存泄露的问题
- Activitys中使用线程导致的内存泄露
- android开发中,可能会导致内存泄露的问题
- android开发中,可能会导致内存泄露的问题
- Android开发,中可能会导致内存泄露的问题
- HashMap中插入null key的过程分析
- 查找大于100M的文件
- Android文件操作中的openFileOutPut和openFileInput
- Android下白盒自动化回归测试junit
- 二路归并排序mergeSort代码实现_legend
- 使用纯粹的C++语言编写COM组件
- HashMap存取过程中改变key值导致的内存泄露
- 用VC进行COM编程所必须掌握的理论知识
- 枚举进程句柄
- MySql数据库连接时DriverManager.getConnection(url,user,pass)出错
- 很期待ES6
- HashMap Hashtable区别
- 归并排序详解_legend
- Firefox 3.6.28 Download
- libgdx 第二节 主菜单界面