热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

java集合容器的特点

一.ArrayList的优缺点:内存用数组来存储元素, 且内部存储的元素可重复,可以存储null元素。且元素的存入取出顺序相同。 优点:查询快&

一.ArrayList的优缺点:内存用数组来存储元素, 且内部存储的元素可重复,可以存储null元素。且元素的存入取出顺序相同。

优点:查询快,知道索引可以快速查找到元素。在所有容器中ArrayList是查询最快的。

缺点:增删慢。因为数组满了以后需要扩容,就是先创建一个原来数组的1.5倍的数组,然后把之前的元素拷贝到一个新的数组中来。这样添加元素的效率就慢慢变低了。数据越多,删除也变得慢。

容量和大小:有三种构造方法

1.无参构造方法:数组的初始容量是10

2.指定数组的初始容量

3.构造方法(传入一个集合):可以将另一个集合中的元素的元素插入到ArrayList中,数组的初始容量就是该集合的大小。

(2)ArrayList里的常用方法:

1.查询操作:get(int index) indexof(Object o) Iteraor() size() isEmpty()

2.修改操作:add(E element) set(int index,E element) remove(int index)

3.批量操作:clear() stream()


二.Linkedlist 链式链表

特点:1.有序性,元素存入的顺序和取出的顺序一致

2.可重复,可以存入重复的值

3.可以为null,可以存储为null的值

优点:增删快,增加时只需记录前后节点是谁,删除时改变前后的节点记录

缺点:查询慢,必须从头节开始查找

Linkedlist常用方法分类

1.查询操作:getFirst() getLast() size() isEmpty()

2.修改操作:add(E e) addFirst(E e)

3.批量操作:listIterator() clear() stream()

但缺少删除数据的方法,Linkedlist删除数据一般是找到匹配项后使用迭代器的rmove方法删除


                     ArrayList                                                    Linkedlist

数据结构             数组                                                                       链表

查询速度             快                                                                            慢

增删速度             慢                                                                            快

内存空间             小,连续                                                                 大,不连续

应用场景             查询较多                                                                 增删较多


三,HashMap

HashMap是以Key-value来存储数据保存在数组中,默认的初始容量为16。

1.元素是无序的,但是根据Key计算出的。

2.key可以为null并且哈希值为零。

3.key不可以相同,重复的key,对应的新的值将会覆盖旧值。

哈希冲突:是不同的key产生了相同的哈希值,发送冲突的原因是哈希值的取值范围,更大的哈希值意味着相同的概率越小,但也需要更大的存储空间。

“树化”是当链表的长度大于8且数组的容量大于等于64时,将链表转换为红黑树,当红黑树中的节点小于6个时,红黑树将转换为链表,这个过程叫做“链化”,在插入元素时,直接在尾部插入,但红黑树还要计算节点的位置,因此相互转化是很好的互补。

扩容:当前元素个数超越临界值时,HashMap就需要扩容,扩容后的容量是之前的两倍

                                       临界值=容量*负载因子

频繁扩容很容易影响HashMap的性能,所以设置合适的初始容量和负载因子很重要。

HashMap常用的方法:

1.查询操作:size()      isEmpty()     *get(O  e )       Containskey(O e)

2.修改操作:*put(K,V)              remove(O e)

3.批量操作:keyset()                clear()


四,LinkedHashMap  (链式哈希映射)

它扩展自哈希映射,有序的

特点:元素的排序顺序

1.元素的添加顺序:元素添加的顺序和元素取出的顺序一致

2.元素的访问顺序:被访问过的元素将会被排到链表的尾部

LinkedHashMap常用的方法分类

1.查询操作:*size()      *isEmpty()          *get(O e)       *ContainsKey(O e)

2.修改操作:   *put(K,v)      *remove(O e)

3.批量删除:*keyset()      *clear()


五,TreeMap  (二叉树映射)

 以二叉树的形式来存储元素,二叉树是红黑树的类型,红黑树拥有自平衡的特点,根据key的值进行排序

特点:

1.对key的排序       2.无序      3.key不可以为null      4.key唯一

优点:对key排序                缺点:无序

TreeMap的常用方法:

1.查询操作:*size()  *isEmpty()   *get(Object)   *containskey(Object)

2.修改操作:*put(K,V)           *remove(Object)

3.批量删除:*keyset()  *clear()   *descendingMap()


六,Hashset

内部使用HashMap来储存元素,所以是无序的,创建Hashset就是创建了一个HashMap。在存储元素的时候将key当做value使用,value再用一个统一的值进行填充即可。这个值便在HashMap内部PRESENT是Object类型。

元素取出的顺序,数组从下标0开始

特点:1.无序。    2.值唯一。 3.值可以为null。

优点:增删改查快。               缺点:无序。

HashSet常用方法:

1.查询操作:*size()  *isEmpty()     *contains()

2.修改操作:*add()   *remove(Object o)    

3.批量删除:*iterater()    *clear().     

HashMap                                   HashSet

key是键,value是值。             用原来Key的位置来存储元素,value用统一的值进行填充


七.LinkedHashSet(链式哈希集合)

它扩展至HashSet,但它的内部使用的是LinkedHashMap,由于LinkedHashMap是有序的,所以

LinkedHashMap也是有序的。使用key值来存储元素,使用值的位置为唯一的值。

LinkedHashSet常用方法分类

1.查询操作:*size()    *isEmpty()

2.修改操作:*add()      *remove()

3. 批量删除:*iterater()      *clear()

                              LinkedHashMap                     LinkedHashSet

存储方式           key是键,value是值                 把key当做存储value的空间,value用统一的值填充

排序顺序         添加顺序,访问顺序                   添加顺序


八.TreeSet

 内部使用的是TreeMap,对元素进行自然排序,自然排序是通过元素的comparaTo方法完成的,自定义排序则需要实现comparaTo接口。

特点:1.对值排序    2.无序    3.值不可以为null   4.值唯一

优点:对值排序           特点:无序

TreeSet的常用方法:

1.查询操作:  *size()      *isEmpty()     *contans(Object O)

2.修改操作:*add()     *remove(Object O)

3.删除操作:*iterator()      *clear()

                      HashSet                                              LinkedHashSet                                        TreeSet

特点:         添加查询快                            添加,删除,修改,有序                                    排序

适用问题:   添加查询性能最佳。            当需要存入取出的顺序一致时。             对元素进行排序


快速失败机制(fail-fast)

        它能够防止多个线程并发修改同一个容器的内容,如果发生了并发修改的情况那么就会触发"快速失败"的机制,也就是抛出并发修改异常。

1.一种容器的保护机制

2.防止多线程同时修改一个容器

3.容器若被修改将抛出异常

       在容器中定义一个modcount属性:用来记录容器修改的次数,初始值为零,只要容器有被操作就会++,在每次获取迭代器的时候,迭代器的时候,迭代器会获取modcount的值,如果两值不相等,就说明有其他的线程修改了容器,并抛出修改异常。

解决方法:使用线程安全的容器类便可以起到线程安全。

CopyOnNriteArrayList类   ConCurrentHashMap类   CopyOnWriterArrayset类


CopyCurrentHashMap类的特点及优点缺点

1.同步:给数组中的每一个头节点加锁,这样一来并发度从原来的1增长到16,理论上数组有多长,并发度就有多少,并发度上去了,效率也就上去了。

2.统计元素的个数:在并发度大的情况下不能在使用一个属性来统计元数对个数,原因是多个线程同时来读取属性的值,然后再对其++,再同时赋给属性,这样一来就产生了线程安全问题,明明有很多线程对其++,结果却是加一。

      为了解决这个线程安全问题,我们给它加锁,这却使得刚刚提升起来的效率又降下来了,获取锁,释放锁耗时资源,于是设计者使用比锁轻量的CAS,使用CAS更新属性时,同一时刻也只有一个线程能更新成功,其余线程更新失败,更新失败的线程再无限循环更新,只到更新成功。

但是却没高到那里去,于是设计者又提出,不妨新增一个数组,让失败的线程先把值累加到数组中去,在此之前各线程需要知道自己里面加的位置,位置的计算方式和HashMap是一样的,取一个随机数,当做是哈希值&(数组长度减一),这个操作等同于数组操作取余,得到的余数就是要累加的位置(下标)累加失败的线程再循环累加,直到累加成功,最终元素个数由单个属性和数组中累加获得。

3.多线程协同扩容:从后往前,每个线程负责一段数据的迁移工作,一段有多长?

关注一下源码。

4.Key和value是不能为空的。

5.区别:                     HashMap                              ConCrrentHashMap 

线程是否安全             不安全                                             安全

扩容                           单线程扩容                                 多线程扩容

统计个数                      size                                baseCont+ConterCell[  ]

key和value能否为空      能                                               不能

6.常用方法:

(1)查询操作: size()        isEmpty()         get(O e)      Containskey(O e)

(2)修改操作:put(K,V)     remove(O e) 

(3)批量操作:keyset()      clear()

特点:1.无序  2.key唯一  3.key与value不可为null  4.线程安全

优点:增删改查快

缺点:无序


为什么ConcurrentHashMap只给头结点加锁就可以保证线程安全呢?

答:Concurrent只针对位置加锁,它不针对具体元素加锁,头结点之所以成为被锁的对象,是因为头结点正好在数组的位置上,它下面的节点都是链在它身后的,另外,头结点是不固定的,所以只针对位置加锁,而增删改查都是通过头结点来进行的。

      所以只要入口每次只进一个线程,就可以保证数据的安全,因此ConcurrentHashMap只给头节点加速就可以了。

总结

Q:为什么只需要给头节点加锁?

A:加锁只针对位置,不针对具体元素。位置上正好放的是头结点,且增删改查都是以头结点作为入口。所以,只需要给头节点加锁即可。

          


推荐阅读
  • Java容器中的compareto方法排序原理解析
    本文从源码解析Java容器中的compareto方法的排序原理,讲解了在使用数组存储数据时的限制以及存储效率的问题。同时提到了Redis的五大数据结构和list、set等知识点,回忆了作者大学时代的Java学习经历。文章以作者做的思维导图作为目录,展示了整个讲解过程。 ... [详细]
  • 本文探讨了C语言中指针的应用与价值,指针在C语言中具有灵活性和可变性,通过指针可以操作系统内存和控制外部I/O端口。文章介绍了指针变量和指针的指向变量的含义和用法,以及判断变量数据类型和指向变量或成员变量的类型的方法。还讨论了指针访问数组元素和下标法数组元素的等价关系,以及指针作为函数参数可以改变主调函数变量的值的特点。此外,文章还提到了指针在动态存储分配、链表创建和相关操作中的应用,以及类成员指针与外部变量的区分方法。通过本文的阐述,读者可以更好地理解和应用C语言中的指针。 ... [详细]
  • 个人学习使用:谨慎参考1Client类importcom.thoughtworks.gauge.Step;importcom.thoughtworks.gauge.T ... [详细]
  • 标题: ... [详细]
  • 集合的遍历方式及其局限性
    本文介绍了Java中集合的遍历方式,重点介绍了for-each语句的用法和优势。同时指出了for-each语句无法引用数组或集合的索引的局限性。通过示例代码展示了for-each语句的使用方法,并提供了改写为for语句版本的方法。 ... [详细]
  • 本文介绍了Swing组件的用法,重点讲解了图标接口的定义和创建方法。图标接口用来将图标与各种组件相关联,可以是简单的绘画或使用磁盘上的GIF格式图像。文章详细介绍了图标接口的属性和绘制方法,并给出了一个菱形图标的实现示例。该示例可以配置图标的尺寸、颜色和填充状态。 ... [详细]
  • 重入锁(ReentrantLock)学习及实现原理
    本文介绍了重入锁(ReentrantLock)的学习及实现原理。在学习synchronized的基础上,重入锁提供了更多的灵活性和功能。文章详细介绍了重入锁的特性、使用方法和实现原理,并提供了类图和测试代码供读者参考。重入锁支持重入和公平与非公平两种实现方式,通过对比和分析,读者可以更好地理解和应用重入锁。 ... [详细]
  • Spring框架《一》简介
    Spring框架《一》1.Spring概述1.1简介1.2Spring模板二、IOC容器和Bean1.IOC和DI简介2.三种通过类型获取bean3.给bean的属性赋值3.1依赖 ... [详细]
  • OpenMap教程4 – 图层概述
    本文介绍了OpenMap教程4中关于地图图层的内容,包括将ShapeLayer添加到MapBean中的方法,OpenMap支持的图层类型以及使用BufferedLayer创建图像的MapBean。此外,还介绍了Layer背景标志的作用和OMGraphicHandlerLayer的基础层类。 ... [详细]
  • 本文介绍了Web学习历程记录中关于Tomcat的基本概念和配置。首先解释了Web静态Web资源和动态Web资源的概念,以及C/S架构和B/S架构的区别。然后介绍了常见的Web服务器,包括Weblogic、WebSphere和Tomcat。接着详细讲解了Tomcat的虚拟主机、web应用和虚拟路径映射的概念和配置过程。最后简要介绍了http协议的作用。本文内容详实,适合初学者了解Tomcat的基础知识。 ... [详细]
  • 本文介绍了Java的集合及其实现类,包括数据结构、抽象类和具体实现类的关系,详细介绍了List接口及其实现类ArrayList的基本操作和特点。文章通过提供相关参考文档和链接,帮助读者更好地理解和使用Java的集合类。 ... [详细]
  • 本文讨论了Kotlin中扩展函数的一些惯用用法以及其合理性。作者认为在某些情况下,定义扩展函数没有意义,但官方的编码约定支持这种方式。文章还介绍了在类之外定义扩展函数的具体用法,并讨论了避免使用扩展函数的边缘情况。作者提出了对于扩展函数的合理性的质疑,并给出了自己的反驳。最后,文章强调了在编写Kotlin代码时可以自由地使用扩展函数的重要性。 ... [详细]
  • Spring常用注解(绝对经典),全靠这份Java知识点PDF大全
    本文介绍了Spring常用注解和注入bean的注解,包括@Bean、@Autowired、@Inject等,同时提供了一个Java知识点PDF大全的资源链接。其中详细介绍了ColorFactoryBean的使用,以及@Autowired和@Inject的区别和用法。此外,还提到了@Required属性的配置和使用。 ... [详细]
  • 欢乐的票圈重构之旅——RecyclerView的头尾布局增加
    项目重构的Git地址:https:github.comrazerdpFriendCircletreemain-dev项目同步更新的文集:http:www.jianshu.comno ... [详细]
  • 本文介绍了Java的公式汇总及相关知识,包括定义变量的语法格式、类型转换公式、三元表达式、定义新的实例的格式、引用类型的方法以及数组静态初始化等内容。希望对读者有一定的参考价值。 ... [详细]
author-avatar
陈汉文爱_290
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有