JAVA 集合

在处理数据的过程中经常会需要一个容器来存储某一类型的数据,Java 中的数组就是这样一种容器。但 Java 中的数组有其局限性,定义后的数组长度不可变,超出数组长度后就不能再存放数据了。而很多时候我们并不知道数据到底有多少,所以就需要有不定长的容器来存放数据,这就是集合,Java 中的集合都采用了泛型实现,可以存入任何类型的对象数据。Java 中的数组:

Java 中的集合主要分为四类:

List 列表,有序,可重复Queue 队列,有序,可重复Set 集合,不可重复Map 映射,无序,键唯一,值不唯一每种集合类型下都包含多个具体的实现类,如:

1. List 列表,有序、可重复

常用的 List 实现类有:ArrayList、LinkedList、Vector、Stack。

1.1 ArrayList 列表

ArrayList 数组列表,有序,可重复,内部是通过 Array 实现。初始化对象时,如果没有传大小,则列表的大小为 DEFAULT_CAPACITY 的默认值 10。当列表容量不够时,继续往列表中追加元素,则通过数组拷贝,对原数组进行扩容,扩容的方式为 "int newCapacity = oldCapacity + (oldCapacity >> 1)",即新数组容量 newCapacity 为 10 + 10/2 = 15。如果一次性追加多个元素时比如 6 ,时候列表最小容量 minCapacity 需要 10 + 6 = 16,新的容量 newCapacity 小于最小容量 minCapacity 则新数组容量取最小容量值 newCapacity = minCapacity。

对数组列表进行插入、删除操作时都需要对数组进行拷贝并重排序。所以如果能知道大概存储多少数据时,尽量初始化初始容量,提升性能。

1.2 LinkedList 双向链表

LinkedList 是双向链表,也即每个元素都有指向前后元素的指针。既然是链表那么顺序读取的效率非常高,而随机读取的效率较低。当随机获取一个 index 位元素时,链表先比较 index 和链表长度 1/2 的大小,小于时从链表头部查找元素,大于时就从链表尾部查找元素。

对比 ArrayList 如果随机读取数据较多时使用 ArrayList 性能高,插入删除较多时使用 LinkedList 性能高。

1.3 Vector 向量,线程安全的列表

与 ArrayList 一样也是通过数组实现的,不同的是 Vector 是线程安全的,也即同一时间下只能有一个线程访问 Vector,线程安全的同时带来了性能的耗损,所以一般都使用 ArrayList。Vector 的扩容也与 ArrayList 不同,可以设置扩容值,默认每次扩容原来的一倍。

1.4 Stack 栈,后进先出(LIFO)

Stack 继承自 Vector 所以也是数组实现的,线程安全的栈。因为 Stack 继承自 Vector 所以就拥有 Vector 中定义的方法,但作为栈数据类型,不建议使用 Vector 中与栈无关的方法,尽量只用 Stack 中的定义的栈相关方法,这样不会破坏栈数据类型。

1.5 ArrayQueue 数组队列,先进后出(FIFO)

ArrayQueue 是数组实现的队列,从队尾加入数据,只能队头删除数据,可随机读取队列数据。

2. Queue 队列,有序、可重复

继承自 Queue 的队列有:ArrayDeque、LinkedList、PriorityQueue。

2.1 ArrayDeque 数组实现的双端队列

ArrayDeque 是队列,但也可以作为栈使用,而且对比 Stack 更高效。作为双端队列那就可以在队列两端插入和删除元素。当追加元素超过容量限制时,则创建一个两边容量的新数组,并将原数组的内容拷贝到新数组中。

2.2 LinkedList 队列也是双向链表

上文 1.2 中已经提过,这里就不赘述了。推荐使用 ArrayDeque。

2.3 PriorityQueue 优先队列,数组实现的二叉树

PriorityQueue 是一个完全二叉树实现的小顶堆(任意一个非叶子节点的权值,都不大于其左右子节点的权值)。

3. Map 映射/字典,无序,键值对,键唯一

常用的 Map 实现有:HashMap、TreeMap、LinkedHashMap

3.1 HashMap 哈希映射/字典

HashMap就是key->value的键值对数据,key是唯一的,而且key和value都可以为null。HashMap和HashTable相似,HashTable实现了线程同步,在 "Object超类解析" 章节中简单介绍过HashTable的数据存储方式。HashMap 是个无序的字典,遍历时不保证元素顺序。HashMap创建时默认会设置初始容量大小(默认16),和装载因子(默认0.75,扩充容量的阀值),装载因子=已存入元素个数/总容量大小。当然这两个值也可以手动设置。

HashMap的数据存储结构如下图:

HashMap当插入一个数据时,先对key值做hash,用得到的值与容器的大小n减1做&运算得到桶的位置,即:i = (n - 1) & hash,i就是桶的位置。在桶中查找有无元素,没有直接插入,有则比较元素key值是否相同,相同用新值替换。

桶的位置计算为什么是 (n - 1) & hash?先看hash值的计算:

hash() 函数对 key 取值后返回一个整数。又因为 HashMap 的容量 n 大小始终为 2 的幂(默认为 16),那么 n - 1 的二进制始终是最高位为 1,其它位为 0 的数,如:10...0,这个数与整数做 & 运算就得到 hash / n 的余数,余数的取值范围在 0 ~ n-1,很巧妙的设计。相关源码,这里截取了部分:

3.2 TreeMap 红黑树实现的 key->value 容器,可排序

红黑树是一种自平衡二叉查找树,具体查看资料。

3.3 LinkedHashMap 链表映射/字典

LinkedHashMap 继承自 HashMap 所以具有 HashMap 的所有特性。同时又实现了双向链表的特性,保留了元素插入顺序。

4. Set 集合,不可重复

常用的 Set 实现有:HashSet、LinkedHashSet、TreeSet、EnumSet。

4.1 HashSet 哈希集合

HashSet是基于HashMap实现的集合,对HashMap做了一些封装。数据结构如图:

与HashMap不同的是元素的保存为链表形式,插入数据时遍历链表查看是否有相同数据,有则返回false,没有返回true。

4.2 LinkedHashSet 链表集合

继承自 HashSet 与 LinkedHashMap 相似,是对 LinkedHashMap 的封装。

4.3 TreeSet 红黑树集合

与 TreeMap 相似。是对 TreeMap 的封装。

本文只是对 Java 中的集合类做了个简单介绍,详细设计请查看源码了解详情。

java中的集合_Java 集合介绍,常用集合类相关推荐

  1. Java中的数据结构之集合

    文章目录 前言 一.集合的基本框架 二.Collection 1.常用方法 2.Iterator 3.foreach循环 4.List 5.Queue 6.Set 三.Map 1.Map实现类 2.M ...

  2. java中对象类型转换_Java中的对象的类型转换介绍(附代码)

    本篇文章给大家带来的内容是关于Java中的对象的类型转换介绍(附代码),有一定的参考价值,有需要的朋友可以参考一下,希望对你有所帮助. 向上转型:子类对象转为父类,父类可以是接口.公式:Father ...

  3. NO.7 Monitor(管程)是什么意思?Java中Monitor(管程)的介绍

    目录 一.Monitor的概念 二.Monitor 基本元素 三.Java 语言对 monitor 的支持 临界区的圈定 monitor object synchronized 关键字 四.管程:并发 ...

  4. 浅析java中的死锁_Java学习笔记五十五(死锁问题)

    多线程死锁问题. 我们知道,多线程可以改善系统的资源利用率,并且可以提高程序的运行效率.但是,多线程也带来了新的问题,即:死锁问题. 1.死锁的概念 死锁可以理解为多个线程为了争夺同一个资源,而出现互 ...

  5. Java 中15种锁的介绍:公平锁,可重入锁,独享锁,互斥锁,乐观锁,分段锁,自旋锁等等...

    http://blog.51cto.com/13919357/2339446 Java 中15种锁的介绍 在读很多并发文章中,会提及各种各样锁如公平锁,乐观锁等等,这篇文章介绍各种锁的分类.介绍的内容 ...

  6. Java 中15种锁的介绍:公平锁,可重入锁,独享锁,互斥锁,乐观锁,分段锁,自旋锁等等

    Java 中15种锁的介绍 在读很多并发文章中,会提及各种各样锁如公平锁,乐观锁等等,这篇文章介绍各种锁的分类.介绍的内容如下: 公平锁 / 非公平锁 可重入锁 / 不可重入锁 独享锁 / 共享锁 互 ...

  7. Java中的模块(Module)入门介绍

    Java中的模块(Module)入门介绍 在Java 9版本中Java 语言引入了一个非常重要的概念:模块(module).module引入了Java代码分组的另一个级别.每个module都包含许多子 ...

  8. java中两种遍历集合的方式_Java中Map集合的两种遍历方式

    Java中的map遍历有多种方法,从最早的Iterator,到java5支持的foreach,再到java8 Lambda,让我们一起来看下Java中Map集合的两种遍历方式! 关于遍历Map集合的几 ...

  9. Java中的不可变集合介绍

    不可变集合 什么是不可变集合? 不可变集合,就是不可被修改的集合. 集合的数据项在创建的时候提供,并且在整个生命周期中都不可改变.否则报错. 为什么创建不可变集合? 如果某个数据不能被修改,把它防御性 ...

最新文章

  1. 【权游相关】龙的简史 | 混乱博物馆
  2. 剑指offer:矩阵中的路径
  3. 聊一聊:开源社区应该用中文吗?
  4. CSDN:因博主近期注重写专栏文章(已超过150篇),订阅博主专栏人数在突增,近期很有可能提高专栏价格(已订阅的不受影响),提前声明,敬请理解!
  5. Oracle EBS-SQL (QA-1):检查超出检验周期的检验数据.sql
  6. String类及其构造器和常用方法
  7. 计算机精英协会考核题 —— 第三题:斐波那契数
  8. 读上瘾-让用户养成习惯
  9. 计算机基础知识总结论文,大学计算机基础总结论文
  10. python中双冒号的作用_python中双冒号
  11. javascript脚本中使用json2.js解析json
  12. UI设计为什么要使用Figma?
  13. 详解策略分析师的日常是怎么样的?策略数据代码篇
  14. 双重差分模型能做固定效应吗_互助问答第213期:模型中的固定效应问题
  15. 仿excel的网页版excel
  16. 键盘连接计算机接口,终于明白电脑如何连接键盘
  17. 中科银谷:企查查天眼查的企业工商数据是从哪里来的?
  18. Matisse图片选择
  19. 密钥创建ssh-keygen
  20. Linux HA Cluster的实例演示(2)

热门文章

  1. 为什么旧硬件的驱动越来越难找了?
  2. 规模比互联网大 30 倍的物联网,如何入门?
  3. 如何避免程序员的大脑超载?
  4. “Hyperledger Fabric 是假区块链!”
  5. @程序员,夏天来了,你该送心仪女生这个啦
  6. 码农们的聚餐,会复杂到什么程度?
  7. 让开发者 so easy 的一站式服务到底存不存在?
  8. 干掉13个区块链最常见的Bug!
  9. 曾经的 Java IDE 王者 Eclipse 真的没落了?21 款插件让它强大起来!
  10. python装饰器语法糖_最全python装饰器的各种写法