java 常用的数据结构

146 阅读3分钟

最近面试经常会问到一些常用的数据结构。所以,在这里总结下。 在JAVA中常用的数据结构有这么三类: 1.List 2.Set 3.Map List可以存储相同的值。主要是包括ArrayList和LinkedList。 Set不可存储相同的值。HashSet是线程不安全的。ConcurrentHashSet是线程安全的。 Map主要用来存储key-value的键值对形式。HashMap是线程不安全的。Concurrent是线程安全的。 先来说说List。其中ArrayList的特点是内部采用数组顺序存储。也就是说他存储数据的内存地址是连续的。那么他适用在什么场合呢? 适用的场合:1.数据连续写入。需要按照Index下标去查找。2;使用index下标增加和删除的次数比较少。 建议:在创建ArrayList的时候,如果能够预估List的数量,最好给个长度。看源码可以知道,当没有给定长度的时候,他初始化的时候会把长度初始化为0.后面添加数据的时候再动态添加长度。因为这样可能发生一个问题。一来,要多次动态去申请内存进行扩容。二来假如这块内存地址没有足够的内存地址可以用来存放新的数据了。这个时候就得在其他内存地址再申请一块连续的内存。。再把数据拷贝过去。 在某个指定位置增加,删除数据,都会造成后面的数据往后挪,以及往前挪。这个工作量非常大。 LinkedList是双向链表。即同时有前驱和后驱节点。支持正向遍历和反向遍历。所以,LinkedList的特点就是内存存储地址并不是连续的。这样有几个优点:1.合理利用碎片内存。2;对于给定位置的增加和删除效率非常高。大家可以想象下。在某个位置增加一个数据。只需要把前面一个数据的后驱地址指向他。然后它的前驱地址指向这个位置-1的前一个数据。后驱位置指向他的位置+1的数据。位置+1的数据的前驱地址指向他就OK。并不涉及数据的拷贝移动。因此他的使用场景是:1.按指定index增加或者删除数据。2.按index查找少。 这里简单聊下为什么按index来查找ArrayList会很高.LinkedList会很低呢? 我们不妨想象成一条街。门牌号是按顺序的。如果有人告诉我们要到100号。我们从1开始,就不用停顺着街道直接往前走100个门店就很容易找到。而如果是LinkedList。我们需要进每一家店里去问下一家店的地址,再到下一家店里去问下下家的地址。这个当然慢啦。(不过其实真正具体的实现是,首先会将size的值除以2,判断index的值小于还是大于等于这个值,如果是小于,说明在前半段,从First往后找,否则就在后半段,从Last往前找。这样保证最多找一半就行)