java集合

1、集合与数组

数组可以存基本数据类型和引用类型,长度固定 集合只能存引用类型,长度不固定

数组 asList 转集合 · 集合 toArray 转数组

2、集合主要类型

   collection:

     list:有序,有下标,可重复

       ArrayList:数组结构,线程不安全 查询快,增删慢 内存可以连续,因此内存使用率低

       Vector:数组结构,线程安全 查询快,增删慢

       LinkList:链表结构,线程不安全,查询慢,增删快 内存可以不连续,因此内存使用率高

     Set:无序,无下标,不可重复

       HashSet:底层是HashMap,HashSet的值存在Map的key上,value统一为present(一个静态的Object对象) 检查重复,先比较hashCode,hashCode相同的情况下再equals,add方法会调用hashMap的put方法

       linkHashSet:底层是linkHashMap treeSet:红黑树结构

   Map:键值对的形式

       HashMap:允许空值,线程不安全,JDK1.7之前数组+链表的形式(链表是为了解决哈希冲突或者叫哈希碰撞),1.8之后,链表长度超过阈值(默认8)时,转换为红黑树

       put的基本过程:新建一个HashMap时,长度为0,当放入第一个元素时,长度设置为默认值16。当存入元素时,会先进行hash运算,获取到哈希码即hashMap中数组对应位置,当对应位置不存在元素时,即将元素放入对应位置。如果对应位置存在别的元素时,则进行equal比较,返回true,说明存在相同元素则进行覆盖,返回false则拼接到链表当中,链表超过8时,转换为红黑树,提高执行效率。当Map中元素超过阈值时,默认是元素个数*0.75,则进行扩容,长度为原来的2倍。 JDK1.8主要解决或优化了一下问题: resize 扩容优化:扩容之后不需要重新计算hash值,元素会保留在原位,或者是原位+扩容大小的位置 引入了红黑树,目的是避免单条链表过长而影响查询效率,红黑树算法请参考 解决了多线程死循环问题,但仍是非线程安全的,多线程时可能会造成数据丢失问题。JDK1.7使用头插法比较快,但在多线程扩容时会引起倒 序和闭环的问题。所以1.8就采用了尾插法。Map的key需要遵循的规则 所有实例遵循equals和hashcode的相关规则。hashMap的长度是2的幂次方 减少hash碰撞,使元素分布更均匀

      linkHashMap:需要实现comparable接口,重写comparato方法,或者建一个构造器compartor,自定义compare方法。

      HashTable:线程安全的HashMap,不允许null,不建议使用

       TreeMap:需要有序遍历的时候用。需要实现comparable接口,重写comparato方法,或者建一个构造器compartor,自定义compare方法。

       conCurrentHashMap:并发HashMap,元素不允许为null,在JDK1.7中,ConcurrentHashMap采用Segment + HashEntry的方式进行实现,结构如 下:一个 ConcurrentHashMap 里包含一个 Segment 数组。Segment 的结构和HashMap类似,是一种数组和链表结构,一个 Segment 包含一个 HashEntry 数组,每个 HashEntry 是一个链表结构的元素,每个 Segment 守护着一个HashEntry数组里的元 素,当对 HashEntry 数组的数据进行修改时,必须首先获得对应的 Segment的锁。

    1、该类包含两个静态内部类 HashEntry 和 Segment ;前者用来封装映射表的键值对,后者用来充当锁的角色;

    2、Segment 是一种可重入的锁 ReentrantLock,每个 Segment 守护一个HashEntry 数组里得元素,当对 HashEntry 数组的数据 进行修改时,必须首先获得对应的 Segment 锁。 在JDK1.8中,放弃了Segment臃肿的设计,取而代之的是采用Node + CAS + Synchronized来保证并发安全进行实现, synchronized只锁定当前链表或红黑二叉树的首节点,这样只要hash不冲突,就不会产生并发,效率又提升N倍。

快速失败制度:fast-fail 多个线程同时操作集合时,有可能触发。比如用迭代器,迭代List时,此时,别的线程对该list进行修改结构操作,就会抛出concurrentmodifycationException。因为迭代器需要用到modCount,来获取下一个元素,当修改List时,会修改modCount的值,从而抛 出异常,触发fast-fail机制。

collections操作集合的工具 Collections.unmodifiableCollection()--使集合不能修改; sort()--排序;reverse--倒序等;synchronizedList--转化为线程安全

遍历集合的方式 for 实现了随机快速查找接口(RandomAccess)的用 增强for 底层也是迭代器,未实现RandomAccess的用 迭代器Iterator 未实现RandomAccess的用,ListIterator,提供了倒序的遍历方式以及增(add)和改(set)的操作

transient修饰,防止被序列化,比敏感信息:密码等,不会被保存到磁盘当中 ArrayList的elementData加上transient修饰:每次序列化的时候,先调用默认的defaultWriteObject()方法,序列化非transient的元素,再对elementData遍历,序列化已存入的元素,从而加快了序列化的速度,同时减小了序列化之后文件的大小。

哈希值

把任意长度的二进制值,映射为固定长度的较小的二进制值,这个更小的二进制值就是哈希值

红黑树,提高执行效率,添加和删除用旋转方法,保持红黑树特性,特点:

1、特殊的二叉树,每个节点要么是红色,要么是黑色

2、根节点必须是黑色

3、空节点的子节点必须是黑色

4、红色节点的子节点必须是黑色

5、节点到任意子孙节点的黑色节点个数相同

 

posted @ 2021-09-13 17:06  松哥的博客  阅读(59)  评论(0)    收藏  举报