JAVA容器全面总结
1 容器体系图
简图:
详图:
2
基础
2.1
Iterator接口
迭代器。
具有的能力:后向迭代、删除。
2.2
Iterable接口
表示一个类具有迭代能力。
提供能力:通过iterator()方法,返回iterator。
2.3
Collection接口
集合接口
继承Iterable,具有迭代能力
新增接口:
Size,isEmpty,contains,toArray,add,remove,以及批量操作,条件操作。
2.4
AbstractCollection抽象类
这不是接口了,是个抽象类,实现了Collection接口
实现了Collection种的大部分方法。
toArray,这个的实现是新new的一个数组,把元素一个个拷贝上去。
2.5
Collection的重要子接口
List、Set、Queue
3
工具类
3.1
Array类
这个类属于java.lang.reflect包,所以可以看出,用的是反射的方法。
然后,这是个final类,不可以new,只是提供static方法。
The {@code Array} class provides static
methods to dynamically create and access Java arrays.
提供静态方法,创建和访问java数组。
提供方法:
NewInstance, getLength,get,getXXX类型,set,setXXX类型,
3.2
Collections类
容器工具类
方法见:https://blog.csdn.net/u013256816/article/details/50924875
- 调用一个空List,Set,Map //静态成员变量
- addAll
- binarySearch 利用二分法在指定的集合中查找元素
- sort
- shuffle //混排。混排算法所做的正好与sort相反:它打乱在一个List中可能有的任何排列的踪迹。
- reverse //反转
- synchronizedXXX //确保所封装的集合线程安全(强同步)
- unmodifiableXXXX //确保所封装的集合不能修改。
4
List
4.1
特征
特征:有顺序可以重复,有顺序所以操作时可以在方法中加入索引参数。
同样继承于Collection的Set则不可排序。
虽然我们一般都用iterator单向遍历list,但List是都是可以用ListIterator迭代器双向迭代的。
4.2
ListIterator
继承自Iterator
增加功能:
前向迭代类的:previous,
索引类:nextIndex,previousIndex
操作类:增加、修改
4.3
List接口
继承自Collection
增加功能:
获取对应的迭代器:listIterator
基于索引/可排序的功能:sort,indexOf,lastIndexOf,subList
4.4
AbstractList抽象类
继承自AbstractCollection
实现List接口
实现了迭代器。
4.4.1
Itr内部类
AbstractList可返回的迭代器。
实现了Iterator,通过int cursor记录迭代位置。
4.4.2
ListItr内部类
AbstractList可返回的迭代器。
继承Itr
增加功能:前向迭代、查看序号、增加、修改。
4.4.3
SubList内部类
AbstractList的内部类,用于计算sublist
算出的sublist的元素与原list共用,只是在使用的时候加了个offset。
4.5
AbstractList的三个重要子类
ArrayList 数组实现的
Vector 也是数组实现的,线程安全的
LinkedList 链表实现的
4.6
ArrayList类
继承自AbstractList
特征:用数组实现。
实现:List、RandomAccess、Cloneable、Serializable
数据存放:transient
Object[] elementData;(transient不序列化)
增加能力:
自动扩容
覆盖了AbstractList的三个内部类。是用数组的方式实现的迭代。
4.7
Vector类
基本同ArrayList
数据存放:protected
Object[] elementData; -- 这个没有用transient
新特性:线程同步,大多数方法都用synchronized修饰了。
4.8
AbstractSequentialList抽象类
继承自AbstractList
实现了一些接口,实现都是依赖于迭代器,但迭代器还是抽象的。
4.9
Queue接口
继承自Collection
特征:先进先出队列
提供接口:offer,poll,remove,element,peek
4.10
Deque接口
继承自Queue
特征:双向列表
提供接口:在Queue的基础上,添加上从头增删,从尾增删的接口。xxxFirst,xxxxLast.
4.11
LinkedList
继承自AbstractSequentialList
实现:List、Deque、Cloneable、Serializable
可以看到,跟ArrayList的区别是实现了Deque,没实现RandomAccess
特征:双向链表实现的。
新增接口:封装了Depue的一些双向列表的一些接口,如 push,pop等
覆盖了AbstractList的内部类ListItr,直接继承自ListIterator。用列表的方式实现迭代。
用途:堆栈、队列、双向列表。
4.12 Stack类
继承自Vector
封装Vector方法实现栈接口:push pop peek
5 Set
5.1 特征
无顺序不可以重复
无序因而不能通过索引操作对象
5.2 Set接口
继承自Collection
没提供新的接口,只是声明这是一个Set类型的Collection
5.3 AbstractSet抽象类
继承自AbstractCollection
实现Set接口
5.4 HashSet类
继承自AbstractSet
实现Set, Cloneable, Serializable
数据结构:private transient HashMap<E,Object> map;
此处可见,HashSet是用HashMap实现的,只是用key存放实际对象,用Vaule存放了一个空的常量。private static final Object PRESENT = new Object();
Iterator是返回key的Iterator。
5.5 LinkedHashSet类
继承自HashSet
实现Set, Cloneable, Serializable
跟HashSet的区别是他是用LinkedHashMap来存放数据的,也就是说,区别就是HashMap和LinkedHashMap的区别。
5.6 SortedSet接口
继承自Set接口
添加了顺序功能接口:
位置:First,last
子Set:subSet,headSet,tailSet
需要一个比较运算。
5.7 NavigableSet接口
继承自SortedSet
添加了导航功能(返回和给定元素有响应关系的元素):
Lower,floor,ceiling,higher,pollFirst,pollLast
5.8 TreeSet类
继承自AbstractSet
实现NavigableSet,Cloneable,Serializable
数据对象:private transient NavigableMap<E,Object> m;
具有排序功能
功能还是依赖于对应的map类。
6 Map
6.1 Map体系图
6.2 特征
6.3 Map接口
并没有继承自Collection,也没有声明iterable,仅仅是声明了一些和Collection类似的方法。
基础方法:Size、isEmpty…
Key相关方法:containsKey、containsValue…
元素操作:get、put、remove…
Collection<V> values();
Set<Map.Entry<K, V>> entrySet();
6.4 AbstractMap抽象类
继承自Map
6.5 HashMap类
extends AbstractMap<K,V>
implements Map<K,V>, Cloneable, Serializable
存数据的地方:transient Node<K,V>[] table; //这里数组的每个Node代表一个桶。
static class Node<K,V> implements Map.Entry<K,V>//node中存放了next node的地址。
实际数据结构如下图:
HashMap 永远都是在链表的表头添加新元素。
6.5.1 自动扩容
随着HashMap中元素的数量越来越多,发生碰撞的概率将越来越大,所产生的子链长度就会越来越长,这样势必会影响HashMap的存取速度。为了保证HashMap的效率,系统必须要在某个临界点进行扩容处理,该临界点就是HashMap中元素的数量在数值上等于threshold(table数组长度*加载因子)。但是,不得不说,扩容是一个非常耗时的过程,因为它需要重新计算这些元素在新table数组中的位置并进行复制处理。所以,如果我们能够提前预知HashMap 中元素的个数,那么在构造HashMap时预设元素的个数能够有效的提高HashMap的性能。
6.5.2 HashMap 的底层数组长度为何总是2的n次方?
对hash取余时,对2^n-1做与运算即可。
这样可以保证最大的利用率和最小的碰撞机会。
6.5.3 Fail-Fast 机制
我们知道 java.util.HashMap 不是线程安全的,因此如果在使用迭代器的过程中有其他线程修改了 map,那么将抛出 ConcurrentModificationException,这就是所谓 fail-fast 策略。
在迭代过程中,判断 modCount 跟 expectedModCount 是否相等,如果不相等就表示已经有其他线程修改了 Map:
注意到 modCount 声明为 volatile,保证线程之间修改的可见性。
6.6 LinkedHashMap类
public class LinkedHashMap<K,V>
extends HashMap<K,V>
implements Map<K,V>
LinkedHashMap继承了HashMap的所用特性,并且还通过额外维护一个双向链表保持了有序性
对于每次put进来Entry,除了将其保存到哈希表中对应的位置上之外,还会将其插入到双向链表的尾部。
static class Entry<K,V> extends HashMap.Node<K,V> {
Entry<K,V> before, after; //节点在原先的基础上,加上了双向列表的属性。
}
LinkedHashMap重写了HashMap 的迭代器,它使用其维护的双向链表进行迭代输出。
6.7 Hashtable类
public class Hashtable<K,V>
extends Dictionary<K,V>
implements Map<K,V>, Cloneable, java.io.Serializable {
Dictionary类是任何可将键映射到相应值的类(如 Hashtable)的抽象父类,每个键和值都是对象。但Dictionary 这个类过时了,新的实现类应该实现Map接口。
HashTable和HashMap几乎功能是相同的,差别:
1、 HashTable是同步的。
2、 HashTable不允许Null做key。
6.8 ConcurrentMap接口
没干啥,只是声明为同步
6.9 ConcurrentHashMap类
public class ConcurrentHashMap<K,V> extends AbstractMap<K,V>
implements ConcurrentMap<K,V>, Serializable {
使用乐观锁(asTabAt)进行同步控制的。
比HashTable(使用synchronized)性能要高的多。
6.10 SortedMap接口
public interface SortedMap<K,V> extends Map<K,V>
比较、排序
6.11 NavigableMap接口
public interface NavigableMap<K,V> extends SortedMap<K,V> {
添加了导航功能(返回和给定元素有响应关系的元素):
Lower,floor,ceiling,higher,pollFirst,pollLast
6.12 TreeMap类
public class TreeMap<K,V>
extends AbstractMap<K,V>
implements NavigableMap<K,V>, Cloneable, java.io.Serializable
TreeMap实现了红黑树的结构,形成了一颗二叉树。
特征:
1、 用红黑树实现了插入时的自然排序
2、 红黑树的好处:平衡二叉树,查询效率高。
7 Java1.8新特性
7.1 Foreach
7.2 Spliterator
8 参考
java容器类总结
https://www.cnblogs.com/wishyouhappy/p/3669198.html
Map 综述(一):彻头彻尾理解 HashMap
https://blog.csdn.net/justloveyou_/article/details/62893086
Map 综述(二):彻头彻尾理解 LinkedHashMap
https://blog.csdn.net/justloveyou_/article/details/71713781
Hashtable 的实现原理
http://wiki.jikexueyuan.com/project/java-collection/hashtable.html
Java集合--TreeMap完全解析
https://www.jianshu.com/p/2dcff3634326
JAVA容器全面总结的更多相关文章
- 【Java心得总结七】Java容器下——Map
我将容器类库自己平时编程及看书的感受总结成了三篇博文,前两篇分别是:[Java心得总结五]Java容器上——容器初探和[Java心得总结六]Java容器中——Collection,第一篇从宏观整体的角 ...
- 【Java心得总结六】Java容器中——Collection
在[Java心得总结五]Java容器上——容器初探这篇博文中,我对Java容器类库从一个整体的偏向于宏观的角度初步认识了Java容器类库.而在这篇博文中,我想着重对容器类库中的Collection容器 ...
- 【Java心得总结五】Java容器上——容器初探
在数学中我们有集合的概念,所谓的一个集合,就是将数个对象归类而分成为一个或数个形态各异的大小整体. 一般来讲,集合是具有某种特性的事物的整体,或是一些确认对象的汇集.构成集合的事物或对象称作元素或是成 ...
- Java 容器(list, set, map)
java容器类库的简化图: (虚线框表示接口, 实线框表示普通的类, 空心箭头表示特定的类实现了接口, 实心箭头表示某个类可以生成箭头所指的类对象) 继承Collection的主要有Set 和 Lis ...
- Java - 容器详解
一.ArrayList 长度可变数组,类似于c++ STL中的vector. 元素以线性方式连续存储,内部允许存放重复元素. 允许对元素进行随机的快速访问,但是向ArrayList中插入和删除元素的速 ...
- Java 容器:Collection 初探之 List
1 ///: JavaBasic//com.cnblogs.pattywgm.day1//CollectionTest.java 2 3 package com.cnblogs.pattywgm.da ...
- java容器---集合总结
思考为什么要引入容器这个概念? Java有多种方式保存对象(应该是对象的引用),例如使用数组时保存一组对象中的最有效的方式,如果你想保存一组基本类型的数据,也推荐使用这种方式,但大家知道数组是具有固定 ...
- 3)Java容器
3)Java容器 Java的集合框架核心主要有三种:List.Set和Map.这里的 Collection.List.Set和Map都是接口(Interface). List lst = new ...
- JAVA容器
JAVA容器 一.容器体系结构 java.util 二.迭代器Iterator<E> 迭代器是一种设计模式,可以遍历并选择序列中的对象,而开发人员并不需要了解该序列的底层结构.迭代器通常被 ...
- Java 容器相关知识全面总结
Java实用类库提供了一套相当完整的容器来帮助我们解决很多具体问题.因为我本身是一名Android开发者,包括我在内很多安卓开发,最拿手的就是ListView(RecycleView)+BaseAda ...
随机推荐
- nginx学习笔记(7)Nginx如何处理一个请求---转载
如何防止处理未定义主机名的请求基于域名和IP混合的虚拟主机一个简单PHP站点配置 基于名字的虚拟主机 Nginx首先选定由哪一个虚拟主机来处理请求.让我们从一个简单的配置(其中全部3个虚拟主机都在端口 ...
- 简述组件化解决方案CTMediator与MGJRouter的主要思想
简述CTMediator CTMediator按照功能的结构来讲,使用时需要实现CTMediator的个三部分. 1.CTMediator类:承担总枢纽,总调度的责任 2.Target_(Modu ...
- ELK 方案
转自:https://blog.csdn.net/enweitech/article/details/81744250 今天临时收到一个企业客户的项目需求,需要对所有WIndows业务服务器的日志进行 ...
- 另一个SqlParameterCollection中已包含SqlParameter(转)
一般情况下,我们定义的一个SqlParameter参数数组,如: SqlParameter[] parms = { new SqlParamete ...
- 【模板 && 拓扑】 Dijkstra 单源最短路径算法
话不多说上代码 链式前向星233 #include<bits/stdc++.h> using namespace std; ,_max=0x3fffffff; //链式前向星 struct ...
- 2 duplicate symbols for architecture“文件冲突”
我在配置第三方库拷贝示例文件中的库文件到新项目完成相关配置之后报下面的错误: 错误的原因是在解决问题之后发现的(第三方库的项目示例demo中的 要拷贝到自己项目中的库 并不需要全部添加到自己 ...
- 莫名其妙的标记之@noescape
Swift 中经常遇到一些不熟悉的关键字, 例如@autoclosure, @noescape...等等, 为什么要加这样的关键字, 我自己写方法的时候什么时候要加, 什么时候不加, 都是应该考虑的问 ...
- Code Signal_练习题_isLucky
Ticket numbers usually consist of an even number of digits. A ticket number is considered lucky if t ...
- 10个经典的Android开源应用项目
Android开发又 将带来新一轮热潮,很多开发者都投入到这个浪潮中去了,创造了许许多多相当优秀的应用.其中也有许许多多的开发者提供了应用开源项目,贡献出他们的智慧和 创造力.学习开源代码是掌握技术的 ...
- Spring Boot -01- 快速入门篇(图文教程)
Spring Boot -01- 快速入门篇(图文教程) 今天开始不断整理 Spring Boot 2.0 版本学习笔记,大家可以在博客看到我的笔记,然后大家想看视频课程也可以到[慕课网]手机 app ...