java集合类介绍
集合类简介
Java 集合,也称作容器,主要是由两大接口 (Interface) 派生出来的:Collection 和 Map
Collecton接口常用的子接口有:List接口、Set接口,和Queue;
Set接口常用的子类有:HashSet类、LinkedHashSet类。
Set、List和Map可以看做集合的三大类:
- List集合是有序集合,集合中的元素可以重复,访问集合中的元素可以根据元素的索引来访问。
- Set集合是无序集合,集合中的元素不可以重复,访问集合中的元素只能根据元素本身来访问(也是集合里元素不允许重复的原因)。
- Map集合中保存Key-value对形式的元素,访问时只能根据每项元素的key来访问其value。
主干,即Collection和Map。
1、Collection是一个接口,是高度抽象出来的集合,它包含了集合的基本操作和属性。Collection包含了List和Set两大分支。
- List是一个有序的队列,每一个元素都有它的索引。第一个元素的索引值是0。List的实现类有LinkedList, ArrayList, Vector, Stack。
- Set是一个不允许有重复元素的集合。Set的实现类有HastSet和TreeSet。HashSet依赖于HashMap,它实际上是通过HashMap实现的;TreeSet依赖于TreeMap,它实际上是通过TreeMap实现的。
2、Map是一个映射接口,即key-value键值对。Map中的每一个元素包含“一个key”和“key对应的value”。AbstractMap是个抽象类,它实现了Map接口中的大部分API。而HashMap,TreeMap,WeakHashMap都是继承于AbstractMap。Hashtable虽然继承于Dictionary,但它实现了Map接口。
3、接下来,再看Iterator。它是遍历集合的工具,即我们通常通过Iterator迭代器来遍历集合。我们说Collection依赖于Iterator,是因为Collection的实现类都要实现iterator()函数,返回一个Iterator对象。ListIterator是专门为遍历List而存在的。
List
ArrayList
ArrayList 是一个用数组实现的集合,支持随机访问,元素有序且可以重复。
每一个ArrayList都有一个初始容量(10),该容量代表了数组的大小。随着容器中的元素不断增加,容器的大小也会随着增加。在每次向容器中增加元素的同时都会进行容量检查,当快溢出时,就会进行扩容操作。所以如果我们明确所插入元素的多少,最好指定一个初始容量值,避免过多的进行扩容操作而浪费时间、效率。
扩容:默认将扩容至原来容量的 1.5 倍:
# 右移一位,相当于1/2
int newCapacity = oldCapacity + (oldCapacity >> 1);
扩容之后是通过数组的拷贝来确保元素的准确性的,所以尽可能减少扩容操作。 ArrayList 的最大存储能力:Integer.MAX_VALUE
如果需要边遍历边 remove ,必须使用 iterator。且 remove 之前必须先 next,next 之后只能用一次 remove。
ArrayList擅长于随机访问。同时ArrayList是非同步的。
查找的效率高,插入和删除需要移动元素效率低。
LinkedList
同样实现List接口的LinkedList与ArrayList不同,ArrayList是一个动态数组,而LinkedList是一个双向循环链表。所以它除了有ArrayList的基本操作方法外还额外提供了get,remove,insert方法在LinkedList的首部或尾部。
由于实现的方式不同,LinkedList不能随机访问,它所有的操作都是要按照双重链表的需要执行。在列表中索引的操作将从开头或结尾遍历列表(从靠近指定索引的一端)。这样做的好处就是可以通过较低的代价在List中进行插入和删除操作。
与ArrayList一样,LinkedList也是非同步的。如果多个线程同时访问一个List,则必须自己实现访问同步。一种解决方法是在创建List时构造一个同步的List:
List list = Collections.synchronizedList(new LinkedList(...));
Vector
与ArrayList相似,但是Vector是同步的。所以说Vector是线程安全的动态数组。它的操作与ArrayList几乎一样。
Stack
Stack继承自Vector,实现一个后进先出的堆栈。
Set
HashSet
HashSet 是一个没有重复元素的集合。它是由HashMap实现的,不保证元素的顺序(这里所说的没有顺序是指:元素插入的顺序与输出的顺序不一致),而且HashSet允许使用null 元素。HashSet是非同步的,如果多个线程同时访问一个哈希set,而其中至少一个线程修改了该set,那么它必须保持外部同步。 HashSet按Hash算法来存储集合的元素,因此具有很好的存取和查找性能。
HashSet的实现方式大致如下,通过一个HashMap存储元素,元素是存放在HashMap的Key中,而Value统一使用一个Object对象。
LinkedHashSet
LinkedHashSet继承自HashSet,其底层是基于LinkedHashMap来实现的,有序,非同步。LinkedHashSet集合同样是根据元素的hashCode值来决定元素的存储位置,但是它同时使用链表维护元素的次序。这样使得元素看起来像是以插入顺序保存的,也就是说,当遍历该集合时候,LinkedHashSet将会以元素的添加顺序访问集合的元素。
TreeSet
TreeSet是一个有序集合,其底层是基于TreeMap实现的,非线程安全。TreeSet可以确保集合元素处于排序状态。TreeSet支持两种排序方式,自然排序和定制排序,其中自然排序为默认的排序方式。当我们构造TreeSet时,若使用不带参数的构造函数,则TreeSet的使用自然比较器;若用户需要使用自定义的比较器,则需要使用带比较器的参数。
Map
HashMap
以哈希表数据结构实现,查找对象时通过哈希函数计算其位置,它是为快速查询而设计的,其内部定义了一个hash表数组(Entry[] table),元素会通过哈希转换函数将元素的哈希地址转换成数组中存放的索引,如果有冲突,则使用散列链表的形式将所有相同哈希地址的元素串起来,可能通过查看HashMap.Entry的源码它是一个单链表结构。
Hashtable
Hashtable继承Map接口,实现一个key-value映射的哈希表。任何非空(non-null)的对象都可作为key或者value。如果相同的对象有不同的hashCode,对哈希表的操作会出现意想不到的结果(期待的get方法返回null),要避免这种问题,只需要牢记一条:要同时复写equals方法和hashCode方法,而不要只写其中一个。
Hashtable是同步的。
LinkedHashMap
LinkedHashMap是HashMap的一个子类,它保留插入的顺序,如果需要输出的顺序和输入时的相同,那么就选用LinkedHashMap。
LinkedHashMap是Map接口的哈希表和链接列表实现,具有可预知的迭代顺序。此实现提供所有可选的映射操作,并允许使用null值和null键。此类不保证映射的顺序,特别是它不保证该顺序恒久不变。
LinkedHashMap实现与HashMap的不同之处在于,后者维护着一个运行于所有条目的双重链接列表。此链接列表定义了迭代顺序,该迭代顺序可以是插入顺序或者是访问顺序。
由于LinkedHashMap需要维护元素的插入顺序,因此性能略低于HashMap的性能,但在迭代访问Map里的全部元素时将有很好的性能,因为它以链表来维护内部顺序。
TreeMap
TreeMap(主要是排序) 是一个有序的key-value集合,非同步,基于红黑树(Red-Black tree)实现,每一个key-value节点作为红黑树的一个节点。TreeMap存储时会进行排序的,会根据key来对key-value键值对进行排序,其中排序方式也是分为两种,一种是自然排序,一种是定制排序,具体取决于使用的构造方法。
相互区别
Vector和ArrayList
- vector是线程同步的,所以它也是线程安全的,而arraylist是线程异步的,是不安全的。如果不考虑到线程的安全因素,一般用arraylist效率比较高。
- ArrayList 和Vector是采用数组方式存储数据,此数组元素数大于实际存储的数据以便增加和插入元素,都允许直接序号索引元素,但是插入数据要设计到数组元素移动 等内存操作,所以索引数据快插入数据慢,Vector由于使用了synchronized方法(线程安全)所以性能上比ArrayList要 差,LinkedList使用双向链表实现存储,按序号索引数据需要进行向前或向后遍历,但是插入数据时只需要记录本项的前后项即可,所以插入数度较快!
ArrayList和LinkedList
- ArrayList是实现了基于动态数组的数据结构,LinkedList基于双向链表的数据结构。
- 对于随机访问get和set,ArrayList觉得优于LinkedList,因为LinkedList要移动指针。
- 对于新增和删除操作add和remove,LinedList比较占优势,因为ArrayList要移动数据。(扩容时需要复制操作)
HashMap与TreeMap
- HashMap通过hashcode对其内容进行快速查找,而TreeMap中所有的元素都保持着某种固定的顺序,如果你需要得到一个有序的结果你就应该使用TreeMap(HashMap中元素的排列顺序是不固定的)。HashMap中元素的排列顺序是不固定的)。
- HashMap通过hashcode对其内容进行快速查找,而TreeMap中所有的元素都保持着某种固定的顺序,如果你需要得到一个有序的结果你就应该 使用TreeMap(HashMap中元素的排列顺序是不固定的)。集合框架”提供两种常规的Map实现:HashMap和TreeMap (TreeMap实现SortedMap接口)。
- 在Map 中插入、删除和定位元素,HashMap 是最好的选择。但如果您要按自然顺序或自定义顺序遍历键,那么TreeMap会更好。使用HashMap要求添加的键类明确定义了hashCode()和 equals()的实现。这个TreeMap没有调优选项,因为该树总处于平衡状态。
HashTable与HashMap
- 历史原因:Hashtable是基于陈旧的Dictionary类的,HashMap是Java 1.2引进的Map接口的一个实现。
- 同步性:Hashtable是线程安全的,也就是说是同步的,而HashMap是线程序不安全的,不是同步的
- 值:只有HashMap可以让你将空值作为一个表的条目的key或value
java集合类介绍的更多相关文章
- 摘抄转载前辈们的Java集合类总结
本文摘自 Blue Sky:http://www.cnblogs.com/hubcarl JAVA 集合类介绍和使用 类关系示意图Iterable(接口) │ └--Collection (接口) ├ ...
- Java集合类简单总结(重学)
java集合类简介(重学) 一.Collection(集合).Map接口两者应该是平行关系吧. 1.Map介绍 Map是以键值(key-value)对来存放的,2个值.通过key来找到value(例: ...
- java集合类(六)About Queue
接上篇“java集合类(五)About Map” 终于来到了java集合类的尾声,太兴奋了,不是因为可以休息一阵了,而是因为又到了开启新知识的时刻,大家一起加油打气!!Come on...Fighti ...
- java集合类(四)About Set
接上篇:java集合类(三)About Iterator & Vector(Stack) 之前,在比较java常见集合类的时候,就了解到一点有关Set的特性.实现类及其要求等,读者可以去温习下 ...
- java集合类(三)About Iterator & Vector(Stack)
接上篇:java集合类学习(二) Talk about “Iterator”: 任何容器类,在插入元素后,还需要取回元素,因为这是容器的最基本工作.对于一般的容器,插入有add()相关方法(List, ...
- java集合类(二)List学习
接上篇 java集合类(一) List接口继承了Collection接口和Iterable接口,即同样含有Collection和 Iterable的特性,还有方法,其基本方法有: 1)有关添加: b ...
- Java集合类操作优化总结
清单 1.集合类之间关系 Collection├List│├LinkedList│├ArrayList│└Vector│ └Stack└SetMap├Hashtable├HashMap└WeakHas ...
- Java集合类操作优化经验总结
本文首先针对 Java 集合接口进行了一些介绍,并对这些接口的实现类进行详细描述,包括 LinkedList.ArrayList.Vector.Stack.Hashtable.HashMap.Weak ...
- java集合介绍(List,Set,Map)
前言 介绍java的常用集合+各个集合使用用例 欢迎转载,请注明作者和出处哦☺ 参考: 1,<Java核心编程技术(第二版)> 2, http://www.cnblogs.com/Litt ...
随机推荐
- Centos7下安装JDK详细过程记录
1.查询系统是否安装了java: [root@bogon ~]# java -version 根据上图显示,系统默认安装了Openjdk,它和我们使用的java jdk有些区别(具体的可度娘),所以需 ...
- 围绕 Kubernetes 的 8 大 DevOps 生产关键实践
本文主要介绍 DevOps 的 8 大关键实践在 Kubernetes 平台下如何落地,结合我们目前基于 Kubernetes 平台的 DevOps 实践谈谈是如何贯彻相关理念的,这里不会对其具体实现 ...
- 解决wampserver 服务无法启动
如图左击选中apache的httpd.conf把文本中的80端口,改成未被占用的端口.
- HTML5-本地存储浅谈
Web Storage是HTML5里面引入的一个类似于cookie的本地存储功能,可以用于客户端的本地存储 sessionStorage && localStorage session ...
- 答应我,别在go项目中用init()了
前言 go的 init函数给人的感觉怪怪的,我想不明白聪明的 google团队为何要设计出这么一个"鸡肋"的机制.实际编码中,我主张尽量不要使用init函数. 首先来看看 init ...
- Python中切片的应用
Python中切片的应用 Python中可以通过切片实现对列表或者字符串取指定范围的操作,实际就是通过对列表或者字符串通过索引进行操作. 具体细节点击廖雪峰Python教程,其中的课后小问题在此记录下 ...
- Java字节流和字符流,是时候总结一下IO流了
目录 从接收输入值说起 字节流读取 字符流读取 Scanner 读取 什么是 IO 流 字节流和字符流 字节流 字节输入流 字节输出流 缓冲流的原理 字符流 字符输入流 字符输出流 为什么字符流需要 ...
- Leedcode算法专题训练(哈希表)
Java 中的 HashSet 用于存储一个集合,可以查找元素是否在集合中.如果元素有穷,并且范围不大,那么可以用一个布尔数组来存储一个元素是否存在.例如对于只有小写字符的元素,就可以用一个长度为 2 ...
- 使用Vue-TreeSelect组件实现公司-部门-人员级联下拉列表的处理
最近在改造原有Bootstrap开发框架,增加一个Vue&Element前端的时候,发现需要处理一个级联更新的过程,就是选择公司,然后更新部门,选择部门,或者人员列表,选择作为主管的一个实现, ...
- 自动化kolla-ansible部署ubuntu20.04+openstack-victoria之镜像制作debian9.6.0-17
自动化kolla-ansible部署ubuntu20.04+openstack-victoria之镜像制作debian9.6.0-17 欢迎加QQ群:1026880196 进行交流学习 制作Ope ...