HashMap的put方法返回值问题
API文档中的描述:

先看一个例子
Map<Character, Integer> map = new HashMap<Character, Integer>();
System.out.println(map.put('a', 0)); // null
System.out.println(map.put('a', 1)); //
System.out.println(map.put('a', 2)); //
System.out.println(map.put('b', 1)); // null
System.out.println(map.put('b', 2)); //
System.out.println(map.get('a')); //
可以看出:put方法的返回值为null或value;
调用put方法时,如果已经存在一个相同的key, 则返回的是前一个key对应的value,同时该key的新value覆盖旧value;
如果是新的一个key,则返回的是null;
通过hashmap的源码可以看出:
map中一个映射不能包含重复的键。每个键最多只能映射一个值。即相同的key在Map中只会有一个与之关联的value存在。
put()方法实现:首先使用hash(key)得到key的hashcode(),hashmap根据获得的hashcode找到要插入的位置所在的链,在这个链里面放的都是hashcode相同的Entry键值对,
在找到这个链之后,会通过equals()方法判断是否已经存在要插入的键值对,而这个equals比较的就是key。
添加对应的key-value这样的键值对node时,如果原本已经存在相同的key,则直接改变对应的value,并返回旧的value;如果不存在相同的key,则插入,在插入链表时,如果链表长度为临界长度TREEIFY_THRESHOLD,再插入任何元素就要变成红黑树。
public V put(K key, V value) {
return putVal(hash(key), key, value, false, true);//put方法调用putVal方法
}
/**
* Implements Map.put and related methods
*
* @param hash hash for key
* @param key the key
* @param value the value to put
* @param onlyIfAbsent if true, don't change existing value
* @param evict if false, the table is in creation mode.
* @return previous value, or null if none
*/
final V putVal(int hash, K key, V value, boolean onlyIfAbsent,
boolean evict) {
Node<K,V>[] tab; Node<K,V> p; int n, i;
if ((tab = table) == null || (n = tab.length) == 0)
n = (tab = resize()).length;
if ((p = tab[i = (n - 1) & hash]) == null)
tab[i] = newNode(hash, key, value, null);
else {
Node<K,V> e; K k;
if (p.hash == hash &&
((k = p.key) == key || (key != null && key.equals(k))))
e = p;
else if (p instanceof TreeNode)
e = ((TreeNode<K,V>)p).putTreeVal(this, tab, hash, key, value);
else {
for (int binCount = 0; ; ++binCount) {
if ((e = p.next) == null) {
p.next = newNode(hash, key, value, null);
if (binCount >= TREEIFY_THRESHOLD - 1) // -1 for 1st
treeifyBin(tab, hash);
break;
}
if (e.hash == hash &&
((k = e.key) == key || (key != null && key.equals(k))))
break;
p = e;
}
}
if (e != null) { // existing mapping for key //key已经存在
V oldValue = e.value; //将已经存在的结点e的value值赋给oldValue
if (!onlyIfAbsent || oldValue == null)//当onlyIfAbsent为false或者oldValue为null时,进行覆盖操作
e.value = value;//覆盖原结点的value值,用新值替换旧值
afterNodeAccess(e);
return oldValue;//返回的是被覆盖的oldValue
}
}
++modCount;
if (++size > threshold)
resize();
afterNodeInsertion(evict);
return null;
}
在hashset中的add方法调用的就是hashmap的put方法,判断put方法的返回值是否等于空,来保证hashset的值不重复。
private transient HashMap<E,Object> map; /**
* Adds the specified element to this set if it is not already present.
* More formally, adds the specified element <tt>e</tt> to this set if
* this set contains no element <tt>e2</tt> such that
* <tt>(e==null ? e2==null : e.equals(e2))</tt>.
* If this set already contains the element, the call leaves the set
* unchanged and returns <tt>false</tt>.
*
* @param e element to be added to this set
* @return <tt>true</tt> if this set did not already contain the specified
* element
*/
public boolean add(E e) {
return map.put(e, PRESENT)==null;
}
HashMap的put方法返回值问题的更多相关文章
- Spring MVC--------处理方法返回值的可选类型
对于Spring MVC处理方法支持支持一系列的返回方式: (1)ModelAndView (2)Model (3)ModelMap (4)Map (5)View (6)String (7)Void ...
- C# 方法返回值的个数
方法返回值类型总的来说分为值类型,引用类型,Void 有些方法显示的标出返回值 public int Add(int a,int b) { return a+b; } 有些方法隐式的返回返回值,我们可 ...
- 使用Result代替ResultSet作为方法返回值
在开发过程中,我们不能将ResultSet对象作为方法的返回值,因为Connection连接一旦关闭,在此连接上的会话和在会话上的结果集也将会自动关闭,而Result对象则不会发生这种现象,所以在查询 ...
- AJAX JQuery 调用后台方法返回值(不刷新页面)
AJAX JQuery 调用后台方法返回值(不刷新页面) (1)无参数返回值(本人亲试返回结果不是预期结果) javascript方法: $(function () { //无 ...
- SpringMVC第五篇【方法返回值、数据回显、idea下配置虚拟目录、文件上传】
Controller方法返回值 Controller方法的返回值其实就几种类型,我们来总结一下-. void String ModelAndView redirect重定向 forward转发 数据回 ...
- 关于java字节流的read()方法返回值为int的思考
我们都知道java中io操作分为字节流和字符流,对于字节流,顾名思义是按字节的方式读取数据,所以我们常用字节流来读取二进制流(如图片,音乐 等文件).问题是为什么字节流中定义的read()方法返回值为 ...
- java 反射获取方法返回值类型
//ProceedingJoinPoint pjp //获取方法返回值类型 Object[] args = pjp.getArgs(); Class<?>[] paramsCls = ne ...
- js 获取getElementsTagName()方法返回值的内容
<div id="news-top" class="section"> <h3>Some title</h3> <di ...
- eclipse自动生成变量名声明(按方法返回值为本地变量赋值)
eclipse自动生成变量名声明(按方法返回值为本地变量赋值) ctrl+2+L 这个快捷键可自动补全代码,极大提升编码效率! 注:ctrl和2同时按完以后释放,再快速按L.不能同时按! 比如写这句代 ...
随机推荐
- lastIndexOf()
方法可返回一个指定的字符串值最后出现的位置,在一个字符串中的指定位置从后向前搜索.
- zabbix监控DELL服务器硬件状态
zabbix监控DELL服务器硬件状态 登录dell服务的管理页面 默认用户名:root 密码:calvin 服务器开放snmp信息,开启完应用 Zabbix服务器导入dell监控硬件模板 验证 sn ...
- zabbix3.4 监控路由器报错No Such Instance currently exists at this OID
zabbix 3.4 监控报错No Such Instance currently exists at this OID 1.首先查看监控的路由器的监控项是否报警 监控主机报错出现这个 No Such ...
- sketch 相关论文
sketch 相关论文 Sketch Simplification We present a novel technique to simplify sketch drawings based on ...
- numpy技巧
矩阵旋转: mat_array = np.array([[1,2],[4,3]]) rotate_90 = np.zeros((2,2), np.uint8) rotate_180 = np.zero ...
- Unity中使用C#实现UDP广播
没有系统的学习过网络,想做联机游戏还真是费劲,想做在局域网内实现自动搜索服务器的功能,然后就想到了使用UDP进行广播,把服务器的信息广播给每一个玩家. Socket udpSocket = new S ...
- Unity Shader 学习之旅
Unity Shader 学习之旅 unityshader图形图像 纸上学来终觉浅,绝知此事要躬行 美丽的梦和美丽的诗一样 都是可遇而不可求的——席慕蓉 一.渲染流水线 示例图 Tips:什么是 GP ...
- Linux常规命令总结
Linux常规命令总结,仅供参考: 系统信息 arch 显示机器的处理器架构(1) uname -m 显示机器的处理器架构(2) uname -r 显示正在使用的内核版本 dmidecode -q 显 ...
- 转载:GBDT算法梳理
学习内容: 前向分布算法 负梯度拟合 损失函数 回归 二分类,多分类 正则化 优缺点 sklearn参数 应用场景 转自:https://zhuanlan.zhihu.com/p/58105824 G ...
- md5sum命令详解
基础命令学习目录首页 原文链接:https://blog.csdn.net/cbbbc/article/details/48563023 前言 在网络传输.设备之间转存.复制大文件等时,可能会出现传输 ...