Java面试题之集合框架库02

1.ArrayDeque、Stack、LinkedList区别

(1)底层数据结构
ArrayDeque:

public class ArrayDeque<E> extends AbstractCollection<E>
                           implements Deque<E>, Cloneable, Serializable

Stack:

public
class Stack<E> extends Vector<E> 

LinkedList:

public class LinkedList<E>
    extends AbstractSequentialList<E>
    implements List<E>, Deque<E>, Cloneable, java.io.Serializable

ArrayDeque实现Deque接口,Stack继承于Vector,LinkedList实现Deque与List接口Stack与Arraydeque、LinkedList都可以作为栈使用
(2)方法
在这里插入图片描述
(3)线程安全
在这里插入图片描述
(4)使用
频繁的插入、删除操作:LinkedList
频繁的随机访问操作:ArrayDeque
未知的初始数据量:LinkedList

2.并发异常 ConcurrentModificationException

modCount 记录对于集合结构修改的次数, 构建迭代器时expectedModCount = modCount,修改集合结构modCount++,迭代器迭代下一元素,发现当前的modCount与期望值expectedModCount不符就会抛出 ConcurrentModificationException
fast-fail机制non-fast fail机制 CopyOnWriteArrayList 线程安全的ArrayList
加锁 + 底层操作都是基于数组的副本实现

3.HashSet,LinkedHashSet、TreeSet之间的区别

Hashset:key和value是一个占位符,当向HashSet结合中存入一个元素时,HashSet会调用该对象的hashCode()方法来得到该对象的hashCode值,然后根据 hashCode值来决定该对象在HashSet中存储位置。
  简单的说,HashSet集合判断两个元素相等的标准是两个对象通过equals方法比较相等,并且两个对象的hashCode()方法返回值相等
LinkedHashSet:LinkedHashSet集合同样是根据元素的hashCode值来决定元素的存储位置,但是它同时使用链表维护元素的次序。这样使得元素看起来像是以插入顺序保存的,也就是说,当遍历该集合时候,LinkedHashSet将会以元素的添加顺序访问集合的元素。
TreeSet:TreeSet类型是J2SE中唯一可实现自动排序的类型
   TreeSet是SortedSet接口的唯一实现类,TreeSet可以确保集合元素处于排序状态。TreeSet支持两种排序方式,自然排序 和定制排序,其中自然排序为默认的排序方式。向 TreeSet中加入的应该是同一个类的对象。
   TreeSet判断两个对象不相等的方式是两个对象通过equals方法返回false,或者通过CompareTo方法比较没有返回0

4.HashMap底层结构(数据结构 + put + hash算法)

HashMap的底层是由数组+链表的形式,数据结构中又叫“链表散列”
HashMap:数组+链表+红黑树
(1)特点
1)快速存储 :比如当我们对hashmap进行get和put的时候速度非常快
2) 快速查找(时间复杂度o(1))当我们通过key去get一个value的时候时间复杂度非常的低,效率非常高
3) 可伸缩:1数组扩容,边长。2,单线列表如果长度超过8的话会变成红黑树
(2)Hash计算
Hash值=(hashcode)^(hashcode >>> 16)
Hashcode予hashcode自己向右位移16位的异或运算。这样可以确保算出来的值足够随机。因为进行hash计算的时候足够分散,以便于计算数组下标的时候算的值足够分散。前面说过hashmap的底层是由数组组成,数组默认大小是16,那么数组下标是怎么计算出来的呢,那就是:
数组下标:hash&(16-1) = hash%16
对哈市计算得到的hash进行16的求余,得到一个16的位数,比如说是1到15之间的一个数,hashmap会与hash值和15进行予运算。这样可以效率会更高。计算机中会容易识别这种向右位移,向左位移。
(3)put方法

public V  put(K key, V value) {
        if (table == EMPTY_TABLE) {
            inflateTable(threshold);//threshold  阈值
        }
        if (key == null)
            return putForNullKey(value);
        int hash = hash(key); //扰动处理后的key的hashcode
        int i = indexFor(hash, table.length);//值应该存放在哪个下标下面
        for (Entry<K,V> e = table[i]; e != null; e = e.next) {
            Object k;  //key 小明   value 13  key 小明   value 12
            if (e.hash == hash && ((k = e.key) == key || key.equals(k))) {  //当有重复的key插入的时候就会替换掉之前的
                V oldValue = e.value;
                e.value = value;
                e.recordAccess(this);
                return oldValue;
            }
        }
5.HashMap和HashTable的区别和联系?

(1)联系
a.都实现了Map接口,保存了Key-Value(键值对)
b.两者的数据结构类似。HashMap和HashTable都是由数组元素为链表头节点的数组组成。
(2)区别
a.继承的父类不同:HashMap继承AbstractMap;HashTable继承Dictionary类
b.HashMap是线程不安全的,而HashTable是线程安全的;
c.HashMap没有contians,只有containsKey和containsValue,认为contians会容易引起误解;
HashTable保留了contains,containsValue和containsKey方法。(但contains和containsValue的功能是相同的)
d.HashTable中key和value都不允许为null;
HashMap中空值可以作为Key,也可以有一个/多个Key的值为空值;
e.扩容方式不同:
HashMap的hash数组默认长度大小为16,扩容方式为2的指数:
HashTable的hash数组默认长度大小为11,扩容方式为两倍加一:

6.Java中的四种引用
  • 强引用 A a = new A(); a是强引用,gc永远不会被引用的对象
  • 软引用 SoftReference 系统将要发生内存溢出的异常,会将软引用对象列入回收范围内进行回收
  • 弱引用 WeakReference 被弱引用关联的对象只能够生存到下一次垃圾回收之前
  • 虚引用 PhantomReference isEnqueued获取到当前被虚引用关联的对象是否被回收
7. ConcurrentHashMap底层原理

ConcurrentHashMap相比HashMap而言,是多线程安全的,其底层数据与HashMap的数据结构相同,数据结构如下:
在这里插入图片描述
(1)ConcurrentHashMap的数据结构(数组+链表+红黑树),桶中的结构可能是链表,也可能是红黑树,红黑树是为了提高查找效率
(2)ConcurrentHashMap继承了AbstractMap抽象类,该抽象类定义了一些基本操作,同时,也实现了ConcurrentMap接口,ConcurrentMap接口也定义了一系列操作,实现了Serializable接口表示ConcurrentHashMap可以被序列化。
(3)内部类
Node类
  Node类主要用于存储具体键值对,其子类有ForwardingNode、ReservationNode、TreeNode和TreeBin四个子类。四个子类具体的代码在之后的具体例子中进行分析讲解。
  Traverser类
  Traverser类主要用于遍历操作,其子类有BaseIterator、KeySpliterator、ValueSpliterator、EntrySpliterator四个类,BaseIterator用于遍历操作。KeySplitertor、ValueSpliterator、EntrySpliterator则用于键、值、键值对的划分。
  CollectionView类
  CollectionView抽象类主要定义了视图操作,其子类KeySetView、ValueSetView、EntrySetView分别表示键视图、值视图、键值对视图。对视图均可以进行操作。
   Segment类
  Segment类在JDK1.8中与之前的版本的JDK作用存在很大的差别,JDK1.8下,其在普通的ConcurrentHashMap操作中已经没有失效,其在序列化与反序列化的时候会发挥作用。
   CounterCell
  CounterCell类主要用于对baseCount的计数。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值