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.不能同时按! 比如写这句代 ...
随机推荐
- 一步步实现一个基本的缓存模块·续, 添加Memcached调用实现
jusfr 原创,转载请注明来自博客园. 在之前的实现中,我们初步实现了一个缓存模块:包含一个基于Http请求的缓存实现,一个基于HttpRuntime.Cache进程级的缓存实现,但观察代码,会发现 ...
- docker-compose 部署 EFK
信息: Docker版本($ docker --version):Docker版本18.06.1-ce,版本e68fc7a 系统信息($ cat /etc/centos-release):CentOS ...
- 小佬頭眼里的读研VS工作
最近小佬頭在各种平台和论坛看到很多临近毕业的本科生在纠结读研和工作.于他们来说,人生到了一个十字路口,需要做出一个选择然后继续前行,今天小佬頭就来聊聊读研和工作的话题. 其实有这个考虑的同学不在少数, ...
- 腾讯云linux+kodexplorer可道云搭建私有云盘
kodexplorer可道云介绍KodExplorer可道云,原名芒果云,是基于Web技术的私有云和在线文件管理系统.致力于为用户提供安全可控.可靠易用.高扩展性的私有云解决方案.用户只需通过简单环境 ...
- 简介make命令和makefile文件
一.为什么要用到 make 命令和 makefile 文件 在 Linux 下编写一个程序,每次编译都需要在命令行一行一行的敲命令.如果是一个很小的程序还好说,命令不怎的复杂,编译速度也挺快,但是对于 ...
- exit命令详解
基础命令学习目录首页 原文链接:https://www.cnblogs.com/itcomputer/p/4157859.html 用途说明 exit命令用于退出当前shell,在shell脚本中可以 ...
- Python3入门机器学习 - k近邻算法
邻近算法,或者说K最近邻(kNN,k-NearestNeighbor)分类算法是数据挖掘分类技术中最简单的方法之一.所谓K最近邻,就是k个最近的邻居的意思,说的是每个样本都可以用它最接近的k个邻居来代 ...
- 让CentOS在同一个窗口打开文件夹
http://www.linuxidc.com/Linux/2010-04/25756.htm
- MathExam6378
我的第一个程序 一.预估与实际 PSP2.1 Personal Software Process Stages 预估耗时(分钟) 实际耗时(分钟) Planning 计划 15 10 • Estima ...
- 学校网站UI设计分析
在一个团队中PM,要更好的掌握项目的实施管理,包括对UI的设计,作为团队项目的PM,在听了老师课上的讲解后,对UI有了新的认识,对此,我对下面网站有了些自己的想法(只可意会不可言传,O(∩_∩)O~) ...