Java集合,队列,链表总结

面向对象

封装 – 隐藏对象的属性和实现细节,仅对外公开接口;

继承 – 子类继承父类的特征和行为;

多态 – 同一个行为具有多个不同表现形式或形态的能力,在继承的基础上。

重载:一个类中多个方法,方法名一样,参数不一样,返回值也可以不一样;
重写:子类对父类的方法的重新实现,在父类中重写扩展子类的方法。

具体的事物用抽象(汽车),行为操作用接口(驾驶)。

开闭原则(Open Close Principle)- 面向扩展开放,面向修改关闭。

单一职责原则(Single Responsibility Principle) – 每一个类应该专注于做一件事情。

里氏替换原则(Liskov Substitution Principle) – 派生类(子类)对象能够替换其基类(超类)对象被使用。

依赖倒置原则(Dependence Inversion Principle) – 实现类尽量依赖抽象类。

接口隔离原则(Interface Segregation Principle) – 尽量拆分庞大臃肿的接口。

String

= – 引用传递,指向内存中的同一个对象。

== – 比较地址(可以为父子类关系)是否相同。

equals – Object 中的 equals 方法是==,String 类重写了 equals 方法,判断的是字符内容是否相同。

clone()-为浅拷贝,仅复制所考虑的对象,而不复制它所引用的对象,所有的对象引用仍然指向原来的对象。

hashcode – 对象根据哈希算法得出的哈希值,它并不是完全唯一的,通常hash集合会先对比 code 值,如果相等在调用 equals 对比,减少equals调用次数,提升效率。

StringBuffer – 线程安全,,内部使用 char 数组来存储数据,内部方法都添加了 synchronized 同步;

StringBuilder – 非同步,但效率高,内部使用 char 数组来存储数据。

Java集合

常见集合分 两大类

继承 Collection接口,底层都由数组实现的 List,Set,Queue;

以及继承 Map接口的 HashMap,HashTable 等。

一种基本类型,必须声明其长度,顺序容器,无法动态调整大小,获取简单,查询一般,增(向后移动)删(向前移动)复杂。
对于数组结构,存储不够时会重新分配内存,把原来数据拷贝过去,在释放原内存(会容易导致程序性能下降,GC 消耗),所以初始化最好估算指定大小。

离散存储结构,不需要申明长度,不是连续的,可动态调整大小,获取复杂,查询复杂,增删简单(只需要改变前后指针指向);
每个元素都分为数据域和指针域,数据域存储实际数据,指针域指向下一个元素的地址。
单向链表:每个结点的指针(next)指向下一个结点,最后一个结点指向为 null,获取数据时需要从第一个指针域开始一个个查找到第N个。
双向链表:结点两个指针,单向链表前提下,第一个结点的pre和最后一个结点的 next 指向为 null;
获取数据会判断下标靠前还是靠后,以此决定从前后链表开始查找。
单向循环链表:在单向链表的基础上,最后一个结点 next 指向 head 结点,形成环。
双向循环链表:在双向链表的基础上,第一个结点的 pre 指向最后一个结点,最后一个结点的 next 指向第一个结点,形成环。

List(有序列表)

存取顺序一致。

数组结构,插入数据顺序,类型为 Object,实现快速查询,非线程安全,中间位置插入或者删除元素时,需要对数组前后数据进行移动(复制),代价比较高;
add 长度不够常情况下正常扩容(gorw()方法)1.5倍,如果扩展数组大小达到最大值,则取最大值。

数组结构,类似 ArrayList,线程安全(只允许一个线程写),java1.0的产物;
add 长度不够常情况下正常扩容(gorw()方法)2倍。

继承自 Vector, 先进后出,添加数据时,存放数组末尾。

双向链表结构的 List,插入顺序排序,因为是链表结构,所以增删效率高,继承 AbstractSequentialList,同时实现了 List 和 Deque 接口,非线程安全;
可以看作一个顺序容器也可以看作一个队列(Queue),同时又可以看作一个栈(Stack),使用上对比 ArrayList 多了一些 push 等方法。

Queue(队列)

先进先出,只允许在一端进行插入操作,另一端进行删除操作的线性表。

数组结构,非线程安全,支持同时从两端添加或移除元素,因此又被称为双端队列,官方也推荐可用来替代 Stack;
数据不能为 null,add 长度不够常情况下正常扩容(doubleCapacity()方法)2倍。

Map(映射)

数组+单向链表结构, 无序的,非线程安全,常用来做统计。
数组下标
根据 key 计算得出 hashcode 值,在重新进行哈希运算(为了避免重复计算,hash 值会缓存在结点的变量上),经过计算(跟数组长度做位与运算)可以得到数组下标。
查找数据:得到数组下标,获取 value。

添加数据

存入数据为 null 会单独处理,存放在数组下标为 0 的位置,如果 key 值不是 null,通过计算到的下标,存入对应下标结点 value 字段中;
如果发生碰撞,添加到同级链表中(本身是链表)。
hash冲突
哈希 冲突的产生是由于不同对象计算出来的 hashCode 可能相同,code 相同意味着计算得到的下标也相同,接下来会判断 key 值是否相同,如果相同,此时冲突产生。
没有 hash 冲突的 map 查询效率比较高,如果发生冲突就会导致这个结点结构形成链,当查询时就需要挨个匹配,影响效率。
树化
在 java8 之前,如果 hash(散列)冲突,首先会使用 链地址法解决,就是链表,把冲突的数据,添加到同一个 hash 值的元素后面,行成一个链;
在 java8 之后,采用红黑树存储,因为红黑树更加适合修改密集型任务。

HashMap 的大小只能是2的N次方,默认大小为16,假设你指定20,会自动转换成32。

LRU:新数据插入到链表头部,每当缓存命中则将数据移到链表头部,当缓存满了,将链表尾部的数据移除。

不能为空,数组+单向链表结构, 无序的,线程安全,实现跟 HashMap 大致一样,官方已经推荐使用 ConcurrentHashMap 替换。

数组+单向链表结构,线程安全,之前使用 分段锁(如果一个线程占用一段,别的线程可以操作别的部分),每个 segment 继承 ReentrantLock;
java1.8 之后改成了 CAS + synchronized 保证并发更新,一把锁只锁住一个链表或者一棵树,并发效率更加提升。

数组+单向链表结构, 自然顺序,非线程安全,相比 HashMap 来说,TreeMap 多继承了 NavigableMap 接口,这个接口决定了 TreeMap 与 HashMap 的不同;

HashMap 的 key 是无序的,TreeMap 的 key 是有序的,也就是自动排序好。

Set(无序列表)

通过 hashCode() 和 equals() 来保证元素的唯一性,首先通过 hashCode 判断可以避免多次 equals,提高效率。

存储的结构是哈希表,基于 HashMap 来存储,非线程安全,数据存入 Key 中,value 使用同一个 Object 对象,节省内存开销,利用 HashMap 的 hash 判断达到去重的效果。

继承自 HashSet,保证了元素存取的顺序,区别在于多了双向链表,内部使用 LinkedHashMap 来存储数据。

基于 TreeMap 来存储, 自然顺序,区别是存储单个对象,不能重复。

Collections.synchronizedMap():内部方法把传入的 map对象用 synchronized 进行上锁。

Original: https://www.cnblogs.com/LiuZhen/p/15918125.html
Author: 翻滚的咸鱼
Title: Java集合,队列,链表总结

原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/580328/

转载文章受原作者版权保护。转载请注明原作者出处!

(0)

大家都在看

  • Feign调用,get请求,参数为对象, 解决请求对象以及参数值为null

    请求参数过多,所以包装成一个请求对象 服务端: @GetMapping(value = "/readInfos") public List readHotels…

    Java 2023年6月8日
    074
  • docker容器实战:原理、架构与应用 廖煜 晏东 PDF下载

    404. 抱歉,您访问的资源不存在。 可能是网址有误,或者对应的内容被删除,或者处于私有状态。 代码改变世界,联系邮箱 contact@cnblogs.com 园子的商业化努力-困…

    Java 2023年6月8日
    088
  • win10系统中修改hosts文件

    进入hosts文件目录 选择以管理员身份打开Windows PowerShell 输入cmd进入管理员界面,输入 notepad hosts编辑hosts文件 posted on2…

    Java 2023年6月15日
    078
  • android多文件上传,java服务端接收

    Android多文件上传,java服务端接收 1、Android端 代码: String uploadUrl = "http://xxx/uploadFiles&quot…

    Java 2023年6月5日
    077
  • Nginx 限流配置

    limit_req_zone 用来限制单位时间内的请求数,即速率限制,采用的漏桶算法 “leaky bucket”。 limit_req_zone $bin…

    Java 2023年5月30日
    079
  • java selenium (六) XPath 定位

    xpath 的定位方法, 非常强大。 使用这种方法几乎可以定位到页面上的任意元素。 什么是xpath xpath 是XML Path的简称, 由于HTML文档本身就是一个标准的XM…

    Java 2023年5月29日
    077
  • 堆的基本储存

    目录 一、概念及其介绍 二、适用说明 三、结构图示 四、Java 实例代码 一、概念及其介绍 堆(Heap)是计算机科学中一类特殊的数据结构的统称。 堆通常是一个可以被看做一棵完全…

    Java 2023年6月5日
    0163
  • 【Javafx】以树状列表的形式显示类(TreeTableView控件的使用)

    在使用Javafx插件开发作业项目时,我需要将房屋以树状表格的形式显示出来。实现的效果: 1、简单介绍 在这里简单介绍一下我的程序中涉及到的类的属性。 在我的程序中,需要显示的类为…

    Java 2023年6月8日
    093
  • SpringBoot整合reids之JSON序列化文件夹操作

    前言 最近在开发项目,用到了redis作为缓存,来提高系统访问速度和缓解系统压力,提高用户响应和访问速度,这里遇到几个问题做一下总结和整理 快速配置 SpringBoot整合red…

    Java 2023年6月13日
    070
  • Moriis神级遍历!

    Moriis 遍历 Morris 遍历是二叉树遍历的一种方式,传统的递归和非递归遍历的时间复杂的都是O(N),空间复杂度都是O(h)(h为树的高度),而 Morris 遍历可以做到…

    Java 2023年6月8日
    094
  • Java 16 新特性:record类

    以前我们定义类都是用 class关键词,但从Java 16开始,我们将多一个关键词 record,它也可以用来定义类。 record关键词的引入,主要是为了提供一种更为简洁、紧凑的…

    Java 2023年6月9日
    074
  • iBoxDB的学习与使用

    1. 引言 说说iBoxDB的优点: 1)无需安装,不像其他数据库比如MongoDB, MySQL 需要安装。iBOXDB只需要某个目录存放最终的数据即可。完全就像操作本地文件一 …

    Java 2023年6月5日
    061
  • Apache Druid数据查询套件详解计数、排名和分位数计算(送JSON-over-HTTP和SQL两种查询详解)

    5. 数据查询 欲看此文,必看如下两篇文章: Druid支持JSON-over-HTTP和SQL两种查询方式。除了标准的SQL操作外,Druid还支持大量的唯一性操作,利用Drui…

    Java 2023年6月15日
    081
  • VMware虚拟机系统无法使用桥接联网

    1、环境 VMware 14.1.1 虚拟系统:Windows Server 2008 32位 2、解决办法 打开虚拟网络编辑器 有红框中的提示出现时,就点击更改设置 点击桥接模式…

    Java 2023年6月5日
    090
  • 路由器配置深入浅出—静态路由和缺省路由配置

    知识域: 实验拓扑: 关键配置: #静态路由配置命令:ip route命令 r(config)#ip route dest_net_id dest_net_mask next_ho…

    Java 2023年6月6日
    076
  • Docker安装Portainer

    Docker安装Portainer Docker介绍 Docker是一个开源的容器引擎,完全使用沙箱机制,相互之间不会有任何接口,并且容器性能开销低,让开发者可以打包应用或者依赖包…

    Java 2023年6月15日
    073
亲爱的 Coder【最近整理,可免费获取】👉 最新必读书单  | 👏 面试题下载  | 🌎 免费的AI知识星球