Java基础--->集合详解

这篇具有很好参考价值的文章主要介绍了Java基础--->集合详解。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

集合

Collection

​ Collection一般存储的是列表数据

List

​ List存储的数据是有序可重复的

ArrayList

​ ArrayList数组存储,可以动态扩容,适合大量查找,线程不安全

// 使用ArrayList进行插入和删除操作时,因为采用数组存储,所以如果执行插入操作时,会默认将元素插入到数组的末尾,这时候时间复杂度为O(1),如果插入到中间位置,时间复杂度就为O(n-1),因为要插入到中间,需要将当前位置和后续的元素向后移一位。
// 支持高效的元素随机访问,可以通过元素的序号快速获取元素对象
// 内存空间浪费主要体现在list列表的结尾会预留一定的容量空间

ArrayList扩容机制

JDK8之前直接创建长度为10的数组elementData,EMPTY_ELEMENTDATA=10是默认值;

JDK8之后只有当add时才初始容量值

ArrayList底层有三种构造器

​ 当创建ArrayList数组时,没有定义初始值,这时候系统给ArrayList赋初始值为10

​ 定义初始值,会进行判断,如果大于0,直接使用定义的初始值,如果等于0,系统赋值默认初始值10,如果小于0,报错

​ 当定义了一个集合对象时,这时候构造器会先将集合转为数组,然后判断数组长度,如果为0,则赋初始值10,如果不为0,判断集合类型是否和ArrayList相同,如果相同直接将该集合赋值给ArrayList,如果不相同,将该集合的长度和元素赋值给ArrayList

ArrayList扩容

​ 当进行新增操作时,判断数组是否需要扩容,就是判断数组需要的容量和当前的容量进行判断,如果大于当前容量,则需要扩容进入grow()方法,首先将数组扩容1.5倍,然后判断数组所需的容量是否小于新扩容的容量,如果大于新扩容的容量,则将新容量赋为数组所需的容量。然后进行判断新长度是否大于最大容量(MAX_ARRAY_SIZE)(Integer.MAX_VALUE-8),如果大于最大容量,则新容量为Integer.MAX_VALUE

LinkedList

​ LinkedList链表存储(双向链表,jdk7之前循环,之后取消了循环链表),适合增、删、改,线程不安全

// 使用LinkedList进行插入和删除操作时,因为采用链表存储,所以头插尾插都不受元素位置影响,时间复杂度为O(1),如果要在指定位置插入元素的话,时间复杂度为O(n),因为需要先将元素移动到指定位置再进行插入。
// 不支持高效的元素随机访问
// 内存空间的花费主要体现在创建存放每一个节点的元素的空间都比ArrayList消耗的空间更多

我们再项目中一般都不会去使用LinkedList,需要用到LinkedList的场景都可以用ArrayList来代替。

Vector

​ Vector数组存储,是List的古老实现类,线程安全

Set

​ Set存储的数据是无序的,也就是存储数据的底层数组并非按照数组索引的位置进行添加,而是根据数据的哈希值决定的;不可重复的,就是说添加元素时,需要同时重写equals()hashCode()方法

comparable 接口实际上是出自java.lang包 它有一个 compareTo(Object obj)方法用来排序

comparator接口实际上是出自 java.util 包它有一个compare(Object obj1, Object obj2)方法用来排序

HashSet

​ 底层数据结构是哈希表,基于HashMap实现的,底层采用HashMap来保存元素

TreeSet

​ 底层是红黑树(自我平衡排序的二叉树),元素是有序的,排序的方式有自然排序和定制排序

LinkedHashSet

​ 底层数据结构是链表+哈希表,内部也是基于HashMap实现的,但是有一点不一样,有链表将Set变得有序,元素插入和取出满足FIFO

Queue

// 按特定的排队规则来确定先后顺序,存储的元素是有序的、可重复的。

`PriorityQueue`: `Object[]` 数组来实现二叉堆

`ArrayQueue`: `Object[]` 数组 + 双指针

Map

​ 底层是键值对存储,key是无序不可重复的,value是无序可以重复的,

HashMap

​ JDK8之前是由数组+链表组成,数组是主体,链表主要是解决哈希冲突而存在的(”拉链法“解决冲突)

​ JDK8之后在解决哈希冲突有了较大的变化,当链表长度大于阈值(默认8)(将链表转换成红黑树前会判断,如果当前数组的长度小于 64,那么会选择先进行数组扩容,而不是转换为红黑树)时,将链表转化为红黑树,以减少搜索时间,Hashtable没有这样的机制

// HashMap是非线程安全的,但是效率高
// 可以存储null的key和value,但是null作为键只能有一个
// 默认初始值大小为16,之后每次扩容容量都会变为原来的两倍
// 如果给定了初始值大小,HashMap会将其扩容为2的的幂次方大小(HashMap 中的tableSizeFor()方法保证)

HashMap底层创建原理

JDK8之前底层是数组+链表,HashMap通过key的hashcode经过扰动函数处理过后得到hash值,然后通过(n-1)&hash判断当前元素存放的位置(n指数组长度),如果当前位置存在元素,则判断该元素与要存入的元素 hash值以及key是否相同,如果相同的话直接覆盖,如果不相同就通过“拉链法”解决冲突。

JDK 8 的 hash 方法 相比于 JDK 7 hash 方法更加简化,但是原理不变。

拉链法:将数组和链表结合,创建一个链表数组,数组中每一个就是一个链表,若遇到哈希冲突,则将冲突的值加到链表中即可,JDK8之后在解决哈希冲突有了较大的变化,当链表长度大于阈值(默认8)(将链表转换成红黑树前会判断,如果当前数组的长度小于 64,那么会选择先进行数组扩容,而不是转换为红黑树)时,将链表转化为红黑树,以减少搜索时间。

ConcurrentHashMap

Java基础--->集合详解

JDK8之前的的底层采用分段的数组+链表实现,JDK8之后底层数据结构和HashMap8的一样,数组+链表/红黑树。

线程安全的实现的方式是,在JDK8之前ConcurrentHashMap对整个桶数组进行了分割(Segment,分段锁),每一把锁只锁一部分容器中的内容;在JDK8及之后放弃了Segment的理念,直接采用数组+链表/红黑树。

在JDK7及之前

一个ConcurrentHashMap里包含一个Segment数组,这个数组大小一旦初始化就不能改变。默认大小为16,也就是默认可以支持16个线程并发。ConcurrentHashMap 是由Segment数组和HashEntry数组组成,Segment继承了 ReentrantLock,所以Segment是一种可重入锁,HashEntry用于存储键值对数据。一个Segment包含一个HashEntry数组,一个HashEntry包含链表结构。每个Segment守护一个HashEntry数组里面的元素,如果要对数据并发写入会被阻塞,不同的Segment的写入可以并发执行的。

在JDK8及之后

ConcurrentHashMap取消了Segment分段锁,采用Node+CAS+Synchronized来保证安全。底层数据结构是数组+链表+红黑树。在这个版本中,Synchronized只锁定当前链表或红黑树的首节点,这样只要hash不冲突,就不会产生并发,就不会影响其他Node的读写,效率大幅提升。

Hashtable

​ 数组+链表组成,数组是Hashtable的主体,链表是主要解决哈希冲突存在的

// Hashtable是线程安全的,因为Hashtable内部的方法都经过synchrnized修饰,基本已经不使用了
// 不可以存储null的key和value,否则会抛空指针异常
// 创建时如果不指定初始值,默认初始大小为11,之后每次扩容,容量都会变为原来的2n+1
// 如果给定了初始值大小,Hashtable会直接使用

LinkedHashMap

​ 继承自HashMap,底层仍然是数组和链表或红黑树组成。

TreeMap

红黑树(自平衡的排序二叉树)

相比于HashMap来说 TreeMap 主要多了对集合中的元素根据键排序的能力以及对集合内元素的搜索的能力。文章来源地址https://www.toymoban.com/news/detail-422713.html

到了这里,关于Java基础--->集合详解的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Java集合-Collection & Map

    1.集合主要是两组:单列集合(Collection) , 双列集合(Map) 2.Collection 接口有两个重要的子接口 List ,Set . 他们的实现子类都是单列集合 3.Map 接口的实现子类 是双列集合,存放的 K-V 单列集合的顶级接口,含有Iterator()方法,主要用于遍历Collection集合中的元素 Collection的所有实现类都有

    2024年02月09日
    浏览(31)
  • Java笔记(15) Collection集合-->List集合

    集合的理解和好处 数组一旦定义,长度即固定,不能修改。要添加新元素需要新建数组,然后循环拷贝,非常麻烦 集合可以动态保存任意多个对象,使用比较方便 提供饿了一系列方便的操作对象的方法:add、remove、set、get等 使用集合添加、删除新元素的示意代码,简洁明了

    2023年04月14日
    浏览(34)
  • 100天精通Python丨基础知识篇 —— 05、7大基础数据类型详解(变量、列表、集合、字典、元组)

    《100天精通Python专栏 - 快速入门到黑科技》 是由 CSDN 内容合伙人丨全站排名 Top 4 的硬核博主 不吃西红柿 倾力打造,专栏分为基础知识篇和黑科技应用篇。 基础知识篇 以理论知识为主,旨在帮助没有语言基础的小伙伴,学习我整理成体系的精华知识,快速入门构建起知识框

    2023年04月18日
    浏览(46)
  • Java笔记(16) Collection集合-->Set集合-->HashSet

    Set是无序集合(添加和取出的顺序不一致,但取出的顺序是固定的),没有索引 不允许重复元素,所以最多包含一个null JDK API中Set接口的实现类有: Abstract, ConcurrentHashMap.KeySetView, ConcurrentSkipListSet, CopyOnWriteArraySet, EnumSet, HashSet, JobStateReasons, LinkedHashSet, TreeSet Set接口和List接口一

    2023年04月15日
    浏览(47)
  • 进阶JAVA篇- Collection 类的常用的API与 Collection 集合的遍历方式

    目录         1.0 Collection 类的说明         1.1 Collection 类中的实例方法         2.0 Collection 集合的遍历方式(重点)         2.1 使用迭代器( Iterator )进行遍历         2.2 使用增强型 for 循环进行遍历         2.3 使用 Java 8的 Stream API 进行遍历(使用 Lambda 表达式进

    2024年02月08日
    浏览(35)
  • 【从零开始学Java66】讲解Java集合中的Collection体系

    本文将为大家详细讲解Java中的Collection体系,这是我们进行开发时经常用到的知识点,也是大家在学习Java中很重要的一个知识点,更是我们在面试时有可能会问到的问题。 文章较长,干货满满,建议大家收藏慢慢学习。文末有本文重点总结,主页有全系列文章分享。技术类问

    2024年02月06日
    浏览(32)
  • 49天精通Java,第23天,Java集合,Collection接口,Iterator接口

    大家好,我是哪吒。 在Java类库中,集合类的基类是Collection接口。

    2023年04月11日
    浏览(31)
  • 从零开始学习 Java:简单易懂的入门指南之Collection集合及list集合(二十一)

    1.1数组和集合的区别 相同点 都是容器,可以存储多个数据 不同点 数组的长度是不可变的,集合的长度是可变的 数组可以存基本数据类型和引用数据类型 集合只能存引用数据类型,如果要存基本数据类型,需要存对应的包装类 1.2集合类体系结构 1.3Collection 集合概述和使用 Collec

    2024年02月10日
    浏览(27)
  • 【JAVA学习笔记】 56 - 开发中如何选择集合实现类,以及Collection工具类

    https://github.com/yinhai1114/Java_Learning_Code/blob/main/IDEA_Chapter14/src/com/yinhai/Collections_.java 目录 项目代码 Collections工具类 一、Collections工具类介绍 1.排序操作: (均为static方法) 2.查找、替换 在开发中,选择什么集合实现类,主要取决于业务操作特点,然后根据集合实现类特性进行 选择

    2024年02月06日
    浏览(33)
  • Java基础--->集合详解

    ​ Collection一般存储的是列表数据 List ​ List存储的数据是有序可重复的 ArrayList ​ ArrayList数组存储,可以动态扩容,适合大量查找,线程不安全 ArrayList扩容机制 : JDK8之前直接创建长度为10的数组elementData,EMPTY_ELEMENTDATA=10是默认值; JDK8之后只有当add时才初始容量值 ArrayLi

    2023年04月23日
    浏览(29)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包