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.不能同时按! 比如写这句代 ...
随机推荐
- Myeclipse提高运行速度的方法
下文是在其他博客拷过来的,借鉴借鉴,留个笔记,哈哈 1.老是弹出Quick update error .关闭myeclipse的Quick Update自动更新功能这个问题的解决办法是关闭自动更新Wi ...
- python OptionParser模块使用
OptionParser是python中用来处理命令行的模块,在我们使用python进行流程化开发中必要的工具 Optparse,它功能强大,而且易于使用,可以方便地生成标准的.符合Unix/Posi ...
- Kubernetes中的网络
一.引子 既然Kubernetes中将容器的联网通过插件的方式来实现,那么该如何解决这个的联网问题呢? 如果你在本地单台机器上运行docker容器的话注意到所有容器都会处在docker0网桥自动分配的 ...
- Java的POI的封装与应用
Java对Excel表格的导出一直是对我有种可怕噩梦的东西,每次对要建立行与列,并一个一个放值,我是从心底拒绝的. 处于项目需求,需要导出表格,于是找到网上一版很好的开发, <不想用POI?几行 ...
- tf导出pb文件,以及如何使用pb文件
先罗列出来代码,有时间再解释 from tensorflow.python.framework import graph_util import tensorflow as tf def export ...
- 局域网arpspoof欺骗获取cookie/图片/密码
开启路由转发功能 查看IP转发功能是否打开 默认是不开起,0,我这里是修改后的,显示1. 修改转发功能,1为允许. 修改成功后再进行Arpspoof欺骗 如果开始劫持后,自己电脑无法联网了 ??? 检 ...
- RBC:Echo设备2020年可为亚马逊贡献100亿美元收入
BI 中文站 12 月 22 日报道 加拿大皇家银行资本市场(RBC Capital Markets)分析师马克-马哈尼(Mark Mahaney)表示,亚马逊是首批将智能音箱引进主流受众的公司之一, ...
- jenkins部署时遇到“似乎无法联网”,导致无法安装默认插件的解决方案
jenkins安装更新时,默认会检查网络连接,而默认的checkulr 是http://www.google.com/ ,国内是无法访问的,所以修改成任意可以访问的地址即可,比如http://www. ...
- Daily Scrum 11.15
今日完成任务: 1.在回答页面显示用户的相关信息 2.重写了搜索方法,并在自己的Demo网站测试成功 3.修改问题实体属性,加入悬赏积分:并在问题列表页面显示问题悬赏分数 遇到困难:一个是对于学长的搜 ...
- 20172319 实验三 《敏捷开发与XP实践》 实验报告
20172319 2018.05.17-30 实验三 <敏捷开发与XP实践> 实验报告 课程名称:<程序设计与数据结构> 学生班级:1723班 学生姓名:唐才铭 学生学号:20 ...