• 1、java集合:java集合详解及类关系图


    List和Set继承自Collection接口。
    Set无序不允许元素重复。HashSet和TreeSet是两个主要的实现类。
    List有序且允许元素重复,支持null对象。ArrayList、LinkedList和Vector是三个主要的实现类。

    Map也属于集合系统,但和Collection接口没关系。Map是key对value的映射集合,其中key列就是一个集合。key不能重复,但是value可以重复。HashMap、TreeMap和Hashtable是三个主要的实现类。

     SortedSet和SortedMap接口对元素按指定规则排序,SortedMap是对key列进行排序。

    ArrayList和vector区别

    ArrayList和Vector都实现了List接口,都是通过数组实现的。
    Vector是线程安全的,而ArrayList是非线程安全的。
    List第一次创建的时候,会有一个初始大小,随着不断向List中增加元素,当List 认为容量不够的时候就会进行扩容。Vector缺省情况下自动增长原来一倍的数组长度,ArrayList增长原来的50%。

    ArrayList和LinkedList区别及使用场景

    1. 区别

    ArrayList底层是用数组实现的,第一次add操作将数组的长度初始化为10,可以认为ArrayList是一个可改变大小的数组。随着越来越多的元素被添加到ArrayList中,其规模是动态增加的,原理数组大小的1.5倍。
    LinkedList底层是通过双向链表实现的,每个节点Node对象包括指向上一个Node对象和指向下一个Node对象,同时LinkedList还实现了Queue接口,所以他还提供了offer(),peek(), poll()等方法。
    LinkedList和ArrayList相比,增删的速度较快。但是查询和修改值的速度较慢。同时,

    2.使用场景

    LinkedList更适合从中间插入或者删除(链表的特性)。
    ArrayList更适合检索和在末尾插入或删除(数组的特性)。

    HashTable实现原理

    (1)是一个线程安全的散列表,存储内容是键值对映射,不支持和null键值对

    (2)继承于Dictionary,实现了Map、Cloneable、java.io.Serializable接口

    (3)线程安全,默认数组长度为11,负载因子为0.75,扩容方式是old*2+1;

    具体原理参考文章:http://www.cnblogs.com/skywang12345/p/3310887.html

    HashMap和HashTable区别

    1).HashTable的方法前面都有synchronized来同步,是线程安全的;HashMap未经同步,是非线程安全的。
    2).HashTable不允许null值(key和value都不可以) ;HashMap允许null值(key和value都可以)。
    3).HashTable有一个contains(Object value)功能和containsValue(Object value)功能一样。
    4).HashTable使用Enumeration进行遍历;HashMap使用Iterator进行遍历。
    5).HashTable中hash数组默认大小是11,增加的方式是old*2+1;HashMap中hash数组的默认大小是16,而且一定是2的指数。
    6).哈希值的使用不同,HashTable直接使用对象的hashCode; HashMap重新计算hash值,而且用与代替求模。

    HashMap实现原理

    (1)基于Hash的map接口非同步实现, 无序且允许null的键值对。

    (2)初始大小为16,默认负载因子0.75。当一个map填满了75%的bucket时候,将会创建原来HashMap大小的2倍的bucket数组,来重新调整map的大小,并将原来的对象放入新的bucket数组中

    (3) put(K key, V value)

         根据key的hashCode值重新计算出hash值(高位计算一次散列,防止低位不变高位变化造成冲突),既而得到这个元素在数组中的位置(下标)如果数组该位置上已经存放有其他元素了,那么在这个位置上的元素将以链表的形式存放,新加入的放在链头,最先加入的放在链尾。如果数组该位置上没有元素,就直接将该元素放到此数组中的该位置上。

    (4) get(Object key)

    计算key的hashCode,找到数组中对应位置的某一元素,然后通过key的equals方法在对应位置的链表中找到需要的元素。

    (5) 重新调整HashMap大小存在什么问题吗?

    重新调整hashMap大小,确实存在竞争,多线程环境,调整大小的过程中,存储在LinkedList中的元素的次序会反过来,因为移动到新的bucket位置的时候,HashMap并不会将元素放在LinkedList的尾部,而是放在头部,这是为了避免尾部遍历(tail traversing)。如果条件竞争发生了,那么就死循环了。

    JDK7 与 JDK8 中关于HashMap的对比

    结构不同:

    JDK7 HashMap结构为 数组+链表 的形式。
    JDK8 HashMap结构为 数组+链表+红黑树 的形式,当桶内元素大于8时,便会树化。

    hash值的计算方式不同

    JDK7 table在创建hashmap时分配空间。
    JDK8 在put的时候分配,如果table为空,则为table分配空间。

    发生冲突时:

    插入链表操,JDK7是头插法,JDK8是尾插法。

    resize操作:

    JDK7 需要重新进行index的计算。
    JDK8 不需要,通过判断相应的位是0还是1,要么依旧是原index,要么是oldCap + 原index。

    JDK7 与 JDK8 中关于ConcurrentHashMap的对比

    结构不同:

    JDK1.7 由Segment数组结构和HashEntry数组结构组成。Segment实际继承自可重入锁(ReentrantLock)
    JDK1.8 直接用Node数组+链表+红黑树的数据结构来实现,并发控制使用Synchronized和CAS来操作,整个看起来就像是优化过且线程安全的HashMap
    

    锁的粒度不同:

    JDK1.7 版本锁的粒度是基于Segment的,包含多个HashEntry,有上限
    JDK1.8 的实现降低锁的粒度,锁的粒度就是HashEntry(首节点)
    

    锁的替代:

    JDK1.8为什么使用内置锁synchronized来代替重入锁ReentrantLock

    因为粒度降低了,在相对而言的低粒度加锁方式,synchronized并不比ReentrantLock差,在粗粒度加锁中ReentrantLock可能通过Condition来控制各个低粒度的边界,更加的灵活,而在低粒度中,Condition的优势就没有了
    
    基于JVMsynchronized优化空间更大,使用内嵌的关键字比使用API更加自然
    

    size操作:

    JDK7 先进行两次无锁统计,相同直接返回,不同再进行加锁统计
    JDK8 扩容和addCount()方法就已经有处理
  • 相关阅读:
    Python 流媒体播放器(基于VLC)转载
    从2011年用工荒现象看中国人口结构的周期波动
    软件供应链安全现状分析
    vue中this.$nextTick()的用法
    C#中几种数据格式保存xls(DataTable 和List 保存xls) DataGridView转DataTable
    element 报错:Unexpected reserved word 'await'
    C# winfrm程序的主入口捕获项目的全部异常
    利用C#怎么获取 List集合中的重复值Linq操作
    cesium 自定义时间轴 通过改变时间设置光照效果[转]
    CESIUM 原理 之 COMMAND拼接【转】
  • 原文地址:https://www.cnblogs.com/zupengliu/p/10804426.html
Copyright © 2020-2023  润新知