Java基础-三大集合

1. 概况

1.1 List,Set,Map区别

答:Java容器分为Collection和Map两大类。List和Set是Collection的子接口。

  • List(解决顺序问题):存储一组有序可重复的对象,实现类有ArrayList、LinkedList和Stack等。
  • Set(元素独一无二):不存在重复的元素,实现类有HashSet、TreeSet等。
  • Map(Key值搜索):键值对存储,Key值不能重复,但能引用相同的对象,实现类有HashMap、ConcurrentHashMap等。

1.2 快速失败

答:快速失败(fail-fast)是Java集合中的错误检测机制。遍历集合过程中,若线程对集合进行增删改,会抛出并发修改异常。

原理

  • 迭代器遍历过程中,使用一个modCount变量。若集合在遍历期间发生改变,modCount就会变化。hasNext()前都会检测modCount变量是否为exceptedModCount值,不是就抛出异常。
  • 无法处理并发。
  • 可以在所有涉及改变modCount的地方加synchronized同步锁避免fail-fast。

还可以将其理解为一种设计原则,当有某种条件导致模块无法正常运行,就立即终止运行,避免下游脏数据/便于排查。

1.3 安全失败

答:安全失败(fail-safe)的集合(JUC包)是多线程下使用的。遍历前先拷贝原有集合内容,在拷贝的集合上遍历。

  • 迭代时是对拷贝集合操作,不会出现并发修改异常;
  • 无法保证读取的数据是最新的数据。(迭代器只有开始遍历时才拿到拷贝,之后原数据发生变动是不知道的)

还可以理解为一种设计原则,当模块遇到错误,不终止执行,而是采用降级策略,尽量往下走。适用于主模块的分支流程。

2.Map接口

2.1 HashMap

答:HashMap是基于Hash算法实现的由数组和链表组合的数据结构,允许使用null值和null键。

总结:用数组存储,将冲突的key对象放入链表中,再发生冲突就在链表中顺序做对比。

2.1.1 插入元素

  • put元素时,利用key的hashCode重新hash计算出当前对象的元素在数组中的下标;
  • 如果出现hash值相同的key,若key相同,则覆盖原始值;若key不同即出现冲突,则将当前的key-value放入链表中
  • java8前用头插法,新来的值代替原有值,原有值被往后推。问题是,扩容后容易形成环形链表。
  • java8后用尾插法。在扩容同时保证链表元素原来的顺序,避免形成环。

2.1.2 读取元素

  • get元素时,找hash值对应的下标,在进一步判断key是否相同,从而找到对应值。

2.1.3 多线程

答:hashmap线程不安全。put/get方法没有同步锁,容易出现上一秒put值,下一秒get的还是原值。

2.2 HashMap和HashTable的区别

  1. 线程安全:HashMap线程不安全;HashTable内部使用synchronized关键字,线程安全。
  2. Null Key支持:HashMap中null可作为Key;HashTable中null不能作key也不能作value。
  3. 效率:HashMap比HashTable效率高一点,而且HashTable基本淘汰了。
  4. 初始容量:HashMap是16,HashTable是11。
  5. 扩容机制:HashMap是当前容量翻倍,Hashtable是当前容量翻倍+1。

2.2.1 为什么HashTable的null不能做key和value

答:两点原因。

  • HashTable在put空值时会抛空指针异常。HashMap做了三目运算的处理,null就设0。
  • 安全失败机制。让此次读取的数据不一定是最新,同时key为null就无法判断key是不存在还是空。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值