java容器的数据结构-ArrayList,LinkList,HashMap
}
}
}
}
}
}
}
}
}
* (first.prev == null && first.item != null)
* (last.next == null && last.item != null)
transient Node<E> last; //last本身也是一个Node,没有next元素,仅仅是指向队列末尾元素的标志
}
}
}
}
}
}
*/
}
}
}
}
迭代器指向的位置是元素之前的位置,如下图所示:

这里假设集合List由四个元素List1、List2、List3和List4组成,当使用语句Iterator it = List.Iterator()时,迭代器it指向的位置是上图中Iterator1指向的位置,当执行语句it.next()之后,迭代器指向的位置后移到上图Iterator2所指向的位置。
Iterator迭代器包含的方法有:
hasNext():如果迭代器指向位置后面还有元素,则返回 true,否则返回false
next():返回集合中Iterator指向位置后面的元素
ListIterator迭代器包含的方法有:
hasNext():以正向遍历列表时,如果列表迭代器后面还有元素,则返回 true,否则返回false
hasPrevious():如果以逆向遍历列表,列表迭代器前面还有元素,则返回 true,否则返回false
next():返回列表中ListIterator指向位置后面的元素
previous():返回列表中ListIterator指向位置前面的元素
static final int DEFAULT_INITIAL_CAPACITY = 1 << 4; // aka 16
static final float DEFAULT_LOAD_FACTOR = 0.75f;
static class Node<K,V> implements Map.Entry<K,V> {
public V put(K key, V value) {
if (key == null)
return putForNullKey(value);
int hash = hash(key); //首先获得key的hash值
int i = indexFor(hash, table.length); //其次计算出应该放在table的哪个位置(桶)
for (Entry<K,V> e = table[i]; e != null; e = e.next) { //桶由链表构成
Object k;
if (e.hash == hash && ((k = e.key) == key || key.equals(k))) {
V oldValue = e.value;
e.value = value; //如果要插入的Mapping的Hash值和key与桶中的某个
e.recordAccess(this); Mapping完全相同,则替换掉它的value值
return oldValue;
}
}
modCount++;
addEntry(hash, key, value, i);
return null;
}
final int hash(Object k) {
int h = 0;
h ^= k.hashCode();
h ^= (h >>> 20) ^ (h >>> 12);
return h ^ (h >>> 7) ^ (h >>> 4);
}
static int indexFor(int h, int length) {
return h & (length-1);
}
当需要插入的key为null时,调用putForNullKey方法处理:
private V putForNullKey(V value) {
for (Entry<K,V> e = table[0]; e != null; e = e.next) {
if (e.key == null) {
V oldValue = e.value;
e.value = value;
e.recordAccess(this);
return oldValue;
}
}
modCount++;
addEntry(0, null, value, 0);
return null;
}
key为null时,调用putForNullKey方法处理: private V putForNullKey(V value) {
for (Entry<K,V> e = table[0]; e != null; e = e.next) {
if (e.key == null) {
V oldValue = e.value; //如果HashMap中有<null,value>这样的Node,则一定是放在table的
e.value = value; 首位置,因为null的hash值为0
e.recordAccess(this);
return oldValue;
}
}
modCount++;
addEntry(0, null, value, 0);
return null;
}
void addEntry(int hash, K key, V value, int bucketIndex) {
if ((size >= threshold) && (null != table[bucketIndex])) {
resize(2 * table.length);
hash = (null != key) ? hash(key) : 0;
bucketIndex = indexFor(hash, table.length);
}
createEntry(hash, key, value, bucketIndex);
}
真正意义上的添加Entry,首先获得链表原来的头节点e,然后构造一个新的节点,使其next指针指向e:
void createEntry(int hash, K key, V value, int bucketIndex) {
Entry<K,V> e = table[bucketIndex];
table[bucketIndex] = new Entry<>(hash, key, value, e);
size++;
}
public V get(Object key) {
if (key == null) //首先判断key是否为null
return getForNullKey();
Entry<K,V> entry = getEntry(key);
return null == entry ? null : entry.getValue();
}
private V getForNullKey() {
for (Entry<K,V> e = table[0]; e != null; e = e.next) {
if (e.key == null)
return e.value;
}
return null;
}
final Entry<K,V> getEntry(Object key) {
int hash = (key == null) ? 0 : hash(key); //首先获得key的hash值
for (Entry<K,V> e = table[indexFor(hash, table.length)];//获得key在table中的index
e != null;
e = e.next) {
Object k;
if (e.hash == hash && //如果完全相同,则返回key对应的Entry
((k = e.key) == key || (key != null && key.equals(k))))
return e;
}
return null;
}
java容器的数据结构-ArrayList,LinkList,HashMap的更多相关文章
- Java 容器 & 泛型:五、HashMap 和 TreeMap的自白
Writer:BYSocket(泥沙砖瓦浆木匠) 微博:BYSocket 豆瓣:BYSocket Java 容器的文章这次应该是最后一篇了:Java 容器 系列. 今天泥瓦匠聊下 Maps. 一.Ma ...
- 理解java容器底层原理--手动实现HashMap
HashMap结构 HashMap的底层是数组+链表,百度百科找了张图: 先写个链表节点的类 package com.xzlf.collection2; public class Node { int ...
- Java 容器源码分析之HashMap多线程并发问题分析
并发问题的症状 多线程put后可能导致get死循环 从前我们的Java代码因为一些原因使用了HashMap这个东西,但是当时的程序是单线程的,一切都没有问题.后来,我们的程序性能有问题,所以需要变成多 ...
- Java中常见数据结构Map之HashMap
之前很早就在博客中写过HashMap的一些东西: 彻底搞懂HashMap,HashTableConcurrentHashMap关联: http://www.cnblogs.com/wang-meng/ ...
- Java容器深入浅出之Map、HashMap、Hashtable及其它实现类
在Java中,Set的底层事实上是基于Map实现的,Map内部封装了一个Entry内部接口,由实现类来封装key-value对,当value值均为null时,key的集合就形成了Set.因此,Map集 ...
- Java容器学习之ArrayList
一.概述 ArrayList是java中十分常用的集合类,继承于AbstractList,并实现了List.RandomAccess.Cloneable和Serializable接口.ArrayLis ...
- Java容器集合类的区别用法
Set,List,Map,Vector,ArrayList的区别 JAVA的容器---List,Map,Set Collection ├List │├LinkedList │├ArrayList │└ ...
- Java 容器相关知识全面总结
Java实用类库提供了一套相当完整的容器来帮助我们解决很多具体问题.因为我本身是一名Android开发者,包括我在内很多安卓开发,最拿手的就是ListView(RecycleView)+BaseAda ...
- Java中List,ArrayList、Vector,map,HashTable,HashMap区别用法
Java中List,ArrayList.Vector,map,HashTable,HashMap区别用法 标签: vectorhashmaplistjavaiteratorinteger ArrayL ...
随机推荐
- C# 图片识别技术(支持21种语言,提取图片中的文字)
图片识别的技术到几天已经很成熟了,只是相关的资料很少,为了方便在此汇总一下(C#实现),方便需要的朋友查阅,也给自己做个记号. 图片识别的用途:很多人用它去破解网站的验证码,用于达到自动刷票或者是批量 ...
- JS如何获取url查询字符串的键和值?
/** * 根据url查询字符串里的键名获取其值 */function getSearchString(key, search) { // 获取URL中?之后的字符 var str = search; ...
- CSS样式表、JS脚本加载顺序与SpringMVC在URL路径中传参数与SpringMVC 拦截器
CSS样式表和JS脚本加载顺序 Css样式表文件要在<head>中先加载,这样网页显示时可以第一次就渲染出正确的布局和样式,网页就不会闪烁,或跳变 JS脚本尽可能放在<body> ...
- iOS 10 获取相册相机权限
AVAudioSession *audioSession = [[AVAudioSession alloc]init]; [audioSession requestRecordPerm ...
- Abp Uow 设计
初始化入口 在AbpKernelModule类中,通过UnitOfWorkRegistrar.Initialize(IocManager) 方法去初始化 /// <summary> /// ...
- ui-router 视图嵌套时指定二级视图显示默认页面
当跳转到user页面时,右边的uiview是为空的,要点击了左侧的导航才能插入模板,如何在路由中设置二级视图的默认显示页面呢? app.config(function($stateProvider, ...
- 为什么在Java中不使用finalize()方法
我们都知道finalize()方法是回收分配给对象的内存之前调用垃圾收集器线程的基本语句.在这篇文章中,我们将会深入这个方法. 这篇文章中的章节: 1.finalize()方法不能保证执行(这个将要用 ...
- Geometric Progression---cf 567C(求组合方式,map离散)
题目链接:http://codeforces.com/contest/567/problem/C 题意就是有n个数现在要让 ai aj ak 构成公比为K的等比数列(i < j < k) ...
- The Highest Mark---hdu5501(问题转化 01背包)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5501 二维数组: #include<stdio.h> #include<iostre ...
- html table表格列数太多添加横向滚动条
HTML的table表格的列数如果太多或者某一列的内容太长,就会导致表格td的内容被挤压变形,对后台的使用体验非常不友好.比如下面的情况: 那么如何在表格列数较多的情况下添加横向滚动条?其实很简单,只 ...