本文是上一篇的继续,补全HashMap剩余部分源码
主要是KeySet实现以及一些java8特性方法签名(实现省略了)
/** * 返回键值集合的一个视图 * * <pre> * 实际是实现key集合的一个引用迭代子,HashMap本身的变更可以在keySet中直接反映出来 * * 如果HashMap在keySet在遍历过程中发生改变(keySet本身的remove除外),则遍历会失败(fast-fail) * * 注意keySet不是一个全功能的java.util.Set的实现,仅支持remove、removeAll、retainAll、clear,不支持add、addAll * 如果调用add,会抛出UnsupportedOperationException,参见AbstracCollection.add() */ @Override public Set<K> keySet() { Set<K> ks; // 实际返回的就是KeySet,这里判断下只是实现lazy load return (ks = keySet) == null ? (keySet = new KeySet()) : ks; } /** * keySet实现内嵌类,基于HashMap本身的。注意不是全功能的set */ final class KeySet extends AbstractSet<K> { // 大部分支持的操作直接调用HashMap对应方法 @Override public final int size() { return size; } @Override public final void clear() { HashMap.this.clear(); } @Override public final boolean contains(Object o) { return containsKey(o); } @Override public final boolean remove(Object key) { return removeNode(hash(key), key, null, false, true) != null; } /** * java8新增的Collection方法实现 */ @Override public final void forEach(Consumer<? super K> action) { Node<K, V>[] tab; if (action == null) throw new NullPointerException(); if (size > 0 && (tab = table) != null) { int mc = modCount; for (int i = 0; i < tab.length; ++i) { for (Node<K, V> e = tab[i]; e != null; e = e.next) action.accept(e.key); } // 这步是fast-fail特性,这里相当于乐观锁。操作过程中不发生结构变更,才认为才做有效 if (modCount != mc) throw new ConcurrentModificationException(); } } // 迭代子 @Override public final Iterator<K> iterator() { return new KeyIterator(); } @Override public final Spliterator<K> spliterator() { return new KeySpliterator<>(HashMap.this, 0, -1, 0, 0); } } @Override public Collection<V> values() { } final class Values extends AbstractCollection<V> { } @Override public Set<Map.Entry<K, V>> entrySet() { } final class EntrySet extends AbstractSet<Map.Entry<K, V>> { } // java8 的Map default方法的重写,未注释的方法含义都是自明//////////////////////// @Override public V getOrDefault(Object key, V defaultValue) { } @Override public V putIfAbsent(K key, V value) { } /** * key和value都匹配时删除 */ @Override public boolean remove(Object key, Object value) { } /** * key和value都匹配时,替换为newValue */ @Override public boolean replace(K key, V oldValue, V newValue) { } /** * key存在时替换value */ @Override public V replace(K key, V value) { } /** * 带默认处理方式的get,如果key存在,则同get,否则就根据mappingFunction计算出value然后put */ @Override public V computeIfAbsent(K key, Function<? super K, ? extends V> mappingFunction) { } /** * 相当于回调方式的replace,如果key不存在不做处理。key存在则根据remappingFunction算出新的value,如果为null,则删除,否则替换 * * @param remappingFunction BiFunction是双参数的Function版本 */ @Override public V computeIfPresent(K key, BiFunction<? super K, ? super V, ? extends V> remappingFunction) { } /** * 全功能的compute,apply(k,null)表示k不存在的默认值回调 apply(k,v)表示k存在的replace回调 apply()返回null表示删除节点 */ @Override public V compute(K key, BiFunction<? super K, ? super V, ? extends V> remappingFunction) { } /** * 与compute类似,不同是key存在的时候用apply(oldValue,value)来计算(BiFunction全部根据value来) */ @Override public V merge(K key, V value, BiFunction<? super V, ? super V, ? extends V> remappingFunction) { } /** * 遍历处理所有元素 */ @Override public void forEach(BiConsumer<? super K, ? super V> action) { } /** * 双参数版的forEach() */ @Override public void replaceAll(BiFunction<? super K, ? super V, ? extends V> function) { } // clone/serialized /////////////////////// /** * 浅克隆,复制所有kv的引用,不复制kv本身的属性 */ @SuppressWarnings("unchecked") @Override public Object clone() { HashMap<K, V> result; try { result = (HashMap<K, V>) super.clone(); } catch (CloneNotSupportedException e) { throw new InternalError(e); } result.reinitialize(); result.putMapEntries(this, false); return result; } final int capacity() { return (table != null) ? table.length : (threshold > 0) ? threshold : DEFAULT_INITIAL_CAPACITY; } /** * 序列化到流 * * @serialData 4字节capacity+4字节size+(keyObject+valueObject)* */ private void writeObject(java.io.ObjectOutputStream s) throws IOException { int buckets = capacity(); s.defaultWriteObject(); s.writeInt(buckets); s.writeInt(size); internalWriteEntries(s); } // 迭代子 //////////////////////////////// /** * 基类,注意add是不支持的 */ abstract class HashIterator { Node<K, V> next; // 下一节点 Node<K, V> current; // 当前节点 int expectedModCount; // for fast-fail int index; // 当前节点下标 HashIterator() { expectedModCount = modCount; Node<K, V>[] t = table; current = next = null; index = 0; if (t != null && size > 0) { // advance to first entry do { // 找到第一个非空节点 } while (index < t.length && (next = t[index++]) == null); } } public final boolean hasNext() { return next != null; } final Node<K, V> nextNode() { Node<K, V>[] t; Node<K, V> e = next; if (modCount != expectedModCount) { // fast-fail throw new ConcurrentModificationException(); } if (e == null) { throw new NoSuchElementException(); } if ((next = (current = e).next) == null && (t = table) != null) { do { // 注意遍历次数是Capacity,不是size } while (index < t.length && (next = t[index++]) == null); } return e; } public final void remove() { Node<K, V> p = current; if (p == null) throw new IllegalStateException(); if (modCount != expectedModCount) throw new ConcurrentModificationException(); current = null; K key = p.key; // 迭代子触发删除节点 removeNode(hash(key), key, null, false, false); expectedModCount = modCount; } } /** * 遍历Key */ final class KeyIterator extends HashIterator implements Iterator<K> { } final class ValueIterator extends HashIterator implements Iterator<V> { } final class EntryIterator extends HashIterator implements Iterator<Map.Entry<K, V>> { } // 分片迭代子(java8) /////////////////////// static class HashMapSpliterator<K, V> { } static final class KeySpliterator<K, V> extends HashMapSpliterator<K, V> implements Spliterator<K> { } static final class ValueSpliterator<K, V> extends HashMapSpliterator<K, V> implements Spliterator<V> { } static final class EntrySpliterator<K, V> extends HashMapSpliterator<K, V> implements Spliterator<Map.Entry<K, V>> { } // 为LinkedHashMap预留的可重写的方法 ////////////////////// Node<K, V> newNode(int hash, K key, V value, Node<K, V> next) { return new Node<>(hash, key, value, next); } // TreeNode转为普通Node用 Node<K, V> replacementNode(Node<K, V> p, Node<K, V> next) { return new Node<>(p.hash, p.key, p.value, next); } // 根据kv生成TreeNode,普通node转TreeNode TreeNode<K, V> newTreeNode(int hash, K key, V value, Node<K, V> next) { return new TreeNode<>(hash, key, value, next); } // 根据单个普通节点生成TreeNode TreeNode<K, V> replacementTreeNode(Node<K, V> p, Node<K, V> next) { return new TreeNode<>(p.hash, p.key, p.value, next); } /** * 重置为空表,clone和readObject调用 */ void reinitialize() { table = null; entrySet = null; keySet = null; values = null; modCount = 0; threshold = 0; size = 0; } // LinkedHashMap重写的回调 void afterNodeAccess(Node<K, V> p) { } void afterNodeInsertion(boolean evict) { } void afterNodeRemoval(Node<K, V> p) { } // 序列化表内容 void internalWriteEntries(java.io.ObjectOutputStream s) throws IOException { Node<K, V>[] tab; if (size > 0 && (tab = table) != null) { for (int i = 0; i < tab.length; ++i) { for (Node<K, V> e = tab[i]; e != null; e = e.next) { s.writeObject(e.key); s.writeObject(e.value); } } } }
相关推荐
hashmap源码 Excellent-Blog-share Welcome to share excellent blogs . 当你的能力还驾驭不了你的目标时,就应该沉下心来历练 当你的才华还撑不起你的野心时,那你就应该静下心来学习 #目录 ###附录 java系列 java8...
java7 hashmap源码 learn-java 学习java源码 集合 并发集合 队列 线程 面试
hashmap源码 learning-record - 学习轨迹记录 10月1号 7月18号 基础算法:反转单向链表 7月16号 7月11号 7月9号 复习 : HashTable和HashMap的区别详解 LeetCode 27. 删除元素(Remove Element) 7月8号 7月5号 复习...
JAVA之hashmap源码分析 Mobile-Dev-Analysis Analysis of android or java 红岩网校工作站移动开发部学员分组学习 为了让大家学的更加坚固,采取小组学习的方式帮助大家学习,同时在学习研究的过程中需要不断的做...
Java集合专题总结:HashMap 和 HashTable 源码学习和面试总结
hashmap源码 Note-For-Java 记录一下java学习过程的重要知识点 1.在java中如果被除数或者除数有一个为浮点类型,0或者0.0是可以用作除数的,结果得正负无穷;取余操作亦是如此。 2.java在7.0之后switch语句case后面...
hashmap源码 Java学习笔记 Effective Java Topic2:插件销毁对象 2. 多参数情况 使用重叠构造器; 使用Build模式【构建器】: new A.Build().set.set.build(); Build模式也适用于类层次结构 递归类型参数 /* * 递归...
随着Java学习的不断深入,发现很多知识在脑海里都是一个个碎片,建此仓库的目的希望把零碎的知识点都整合起来,提高自己的学习效率。欢迎志同道合的朋友,一起来维护该仓库 目录 网络基础 WEB TCP协议 HTTP/HTTPS ...
jdk源码学习 JavaSourceLearn 版本号 版本 corretto-1.8.0_275 方式 逐步阅读源码添加注释、notes文件夹添加笔记 计划学习任务计划 标题为包名,后面序号为优先级1-4,优先级递减 java.lang Object 1 String 1 ...
缓慢更新一些个人学习java相关源码过程中的笔记,在这里你将不可避免地看到以下情况: 个别不懂/没想好的地方留空待补全 限于个人水平出现的解读错误 编辑错误 排版不统一 如发现有错,欢迎指正! 如果对你有用,...
hashmap源码 to-be-architect to be a Java architect,you should learn these.This page is updated irregularly. Java基础 深入分析 Java SPI 机制和原理 并发编程专题 Executors线程池 线程池ThreadPoolExecutor...
hashmap源码 [toc] java网络编程学习 简介 用于存放学习java网络编程过程遇见的重难点笔记和相关代码 附带代码大部分是《java网络编程 第四版》的课程代码 对运算字符串进行识别的作业 @since2020.11.26 IO流 - 多...
NULL 博文链接:https://zhangshixi.iteye.com/blog/672697
hashmap源码 java-godliness 进步学习java 8 9 后续版本,与时俱进,不能停留在之前的版本 目前这边的代码 按照 java 9 看的 #反射 1.jdbc 2.json #lang包和常用类 #java lambdas and stream #集合 #线程池 pool #IO...
java学习笔记,包括JVM,并发,JDK一些工具的源码,spring,hashMap实现源码分析
hashmap源码 J2SE 新增Shenandoah低暂停时间垃圾回收器算法(实验性功能) 添加一个基本的microbenchmark套件 增强switch表达式(预览功能) 引入JVM常量API 只保留一个64位AARCH64端口 64位平台上使用默认CDS存档 增强...
java版飞机大战源码 curated-article 收集各大技术社区网站每日热文, 在此 每日更新,展示最近7天的数据,更早的数据可以 进行查看,欢迎关注,点个star呀 2021-06-04 CSDN 数据结构与算法 : Liziba-HashMap详解之一...
源码 目录 Java 基础 容器 并发 JVM I/O Java 8 编程规范 网络 操作系统 Linux相关 数据结构与算法 数据结构 算法 数据库 MySQL Redis 系统设计 常用框架 Spring ZooKeeper 权限认证 设计模式 数据通信 网站架构 ...
源码学习 equals 编码规范 注解-未总结 :spider_web:前端 :revolving_hearts:数据结构和算法 CH LFU LRU :woman_biking:网络 :hollow_red_circle:操作系统 Linux :information:数据库 Oracle MYQL 事务 - 未学习 ...
学习笔记(持续更新中) 所有文章均同步发布到微信公众号【JavaRobot】,关注微信公众号,及时得到文章推送,谢谢支持。 说明:如无特别说明,所有代码都基于JDK8 JavaSE(Java基础) Java Core 关键字 synchronized...