Java集合总结【面试题+脑图】,将知识点一网打尽!

前言

声明,本文用的是jdk1.8java

花了一个星期,把Java容器核心的知识过了一遍,感受集合已经无所畏惧了!!(哈哈哈....),如今来总结一下吧~~面试

回顾目录:数组

Java容器可分为两大类:安全

  • Collection
    • List
      • ArrayList
      • LinkedList
      • Vector(了解,已过期)
    • Set
      • HashSet
        • LinkedHashSet
      • TreeSet
  • Map
    • HashMap
      • LinkedHashMap
    • TreeMap
    • ConcurrentHashMap
    • Hashtable(了解,,已过期)

着重标出的那些就是咱们用得最多的容器。微信

其实,我也不知道要怎么总结好,由于以前写每一篇的时候都总结过了。如今又把他们从新罗列出来好像有点水,因此,我决定去回答一些Java容器的面试题!多线程

固然了,个人答案未必就是正确的。若是有错误的地方你们多多包含,但愿不吝在评论区留言指正~~并发

1、ArrayList和Vector的区别

共同点:app

  • 这两个类都实现了List接口,它们都是有序的集合(存储有序),底层是数组。咱们能够按位置索引号取出某个元素,容许元素重复和为null

区别:框架

  • 同步性:
    • ArrayList是非同步的
    • Vector是同步的
    • 即使须要同步的时候,咱们可使用Collections工具类来构建出同步的ArrayList而不用Vector
  • 扩容大小:
    • Vector增加原来的一倍,ArrayList增加原来的0.5倍

2、HashMap和Hashtable的区别

共同点:工具

  • 从存储结构和实现来说基本上都是相同的,都是实现Map接口~

区别:

  • 同步性:
  • 是否容许为null:
    • HashMap容许为null
    • Hashtable不容许为null
  • contains方法
    • 这知识点是在牛客网刷到的,没想到这种题还会有(我不太喜欢)....
    • Hashtable有contains方法
    • HashMap把Hashtable的contains方法去掉了,改为了containsValue和containsKey
  • 继承不一样:
    • HashMap<K,V> extends AbstractMap<K,V>
    • public class Hashtable<K,V> extends Dictionary<K,V>

3、List和Map的区别

共同点:

  • 都是Java经常使用的容器,都是接口(ps:写出来感受好像和没写同样.....)

不一样点:

  • 存储结构不一样
    • List是存储单列的集合
    • Map存储的是key-value键值对的集合
  • 元素是否可重复
    • List容许元素重复
    • Map不容许key重复
  • 是否有序
    • List集合是有序的(存储有序)
    • Map集合是无序的(存储无序)

4、Set里的元素是不能重复的,那么用什么方法来区分重复与否呢? 是用==仍是equals()?

咱们知道Set集合实际大都使用的是Map集合的put方法来添加元素

以HashSet为例,HashSet里的元素不能重复,在源码(HashMap)是这样体现的:

// 1. 若是key 相等 
    if (p.hash == hash &&
        ((k = p.key) == key || (key != null && key.equals(k))))
        e = p;
	// 2. 修改对应的value
	   if (e != null) { // existing mapping for key
            V oldValue = e.value;
            if (!onlyIfAbsent || oldValue == null)
                e.value = value;
            afterNodeAccess(e);
            return oldValue;
       }
复制代码

添加元素的时候,若是key(也对应的Set集合的元素)相等,那么则修改value值。而在Set集合中,value值仅仅是一个Object对象罢了(该对象对Set自己而言是无用的)。

也就是说:Set集合若是添加的元素相同时,是根本没有插入的(仅修改了一个无用的value值)!从源码(HashMap)中也看出来,==和equals()方法都有使用

5、Collection和Collections的区别

  1. Collection是集合的上级接口,继承它的有Set和List接口
  2. Collections是集合的工具类,提供了一系列的静态方法对集合的搜索、查找、同步等操做

6、说出ArrayList,LinkedList的存储性能和特性

ArrayList的底层是数组,LinkedList的底层是双向链表。

  • ArrayList它支持以角标位置进行索引出对应的元素(随机访问),而LinkedList则须要遍历整个链表来获取对应的元素。所以通常来讲ArrayList的访问速度是要比LinkedList要快的
  • ArrayList因为是数组,对于删除和修改而言消耗是比较大(复制和移动数组实现),LinkedList是双向链表删除和修改只须要修改对应的指针便可,消耗是很小的。所以通常来讲LinkedList的增删速度是要比ArrayList要快的

6.1扩展:

ArrayList的增删未必就是比LinkedList要慢。

  • 若是增删都是在末尾来操做【每次调用的都是remove()和add()】,此时ArrayList就不须要移动和复制数组来进行操做了。若是数据量有百万级的时,速度是会比LinkedList要快的。(我测试过)
  • 若是删除操做的位置是在中间。因为LinkedList的消耗主要是在遍历上,ArrayList的消耗主要是在移动和复制上(底层调用的是arraycopy()方法,是native方法)。
    • LinkedList的遍历速度是要慢于ArrayList的复制移动速度的
    • 若是数据量有百万级的时,仍是ArrayList要快。(我测试过)

7、Enumeration和Iterator接口的区别

这个我在前面的文章中也没有详细去讲它们,只是大概知道的是:Iterator替代了Enumeration,Enumeration是一个旧的迭代器了。

与Enumeration相比,Iterator更加安全,由于当一个集合正在被遍历的时候,它会阻止其它线程去修改集合

  • 咱们在作练习的时候,迭代时会不会常常出错,抛出ConcurrentModificationException异常,说咱们在遍历的时候还在修改元素。
  • 这其实就是fail-fast机制~具体可参考博文:blog.csdn.net/panweiwei19…

区别有三点:

  • Iterator的方法名比Enumeration更科学
  • Iterator有fail-fast机制,比Enumeration更安全
  • Iterator可以删除元素,Enumeration并不能删除元素

8、ListIterator有什么特色

  • ListIterator继承了Iterator接口,它用于遍历List集合的元素
  • ListIterator能够实现双向遍历,添加元素,设置元素

看一下源码的方法就知道了:

9、并发集合类是什么?

Java1.5并发包(java.util.concurrent)包含线程安全集合类,容许在迭代时修改集合

  • Utils包下的集合迭代器被设计为fail-fast的,会抛出ConcurrentModificationException。但java.util.concurrent的并不会,感谢评论区提醒~
  • 一部分类为:
    • CopyOnWriteArrayList
    • ConcurrentHashMap
    • CopyOnWriteArraySet

10、Java中HashMap的key值要是为类对象则该类须要知足什么条件?

须要同时重写该类的hashCode()方法和它的equals()方法

  • 从源码能够得知,在插入元素的时候是先算出该对象的hashCode。若是hashcode相等话的。那么代表该对象是存储在同一个位置上的。
  • 若是调用equals()方法,两个key相同,则替换元素
  • 若是调用equals()方法,两个key不相同,则说明该hashCode仅仅是碰巧相同,此时是散列冲突,将新增的元素放在桶子上

通常来讲,咱们会认为:只要两个对象的成员变量的值是相等的,那么咱们就认为这两个对象是相等的!由于,Object底层比较的是两个对象的地址,而对咱们开发来讲这样的意义并不大~这也就为何咱们要重写equals()方法

重写了equals()方法,就要重写hashCode()的方法。由于equals()认定了这两个对象相同,而同一个对象调用hashCode()方法时,是应该返回相同的值的!

11、与Java集合框架相关的有哪些最好的实践

  1. 根据须要肯定集合的类型。若是是单列的集合,咱们考虑用Collection下的子接口ArrayList和Set。若是是映射,咱们就考虑使用Map~
  2. 肯定完咱们的集合类型,咱们接下来肯定使用该集合类型下的哪一个子类~我认为能够简单分红几个步骤:
    • 是否须要同步
      • 去找线程安全的集合类使用
    • 迭代时是否须要有序(插入顺序有序)
      • 去找Linked双向列表结构的
    • 是否须要排序(天然顺序或者手动排序)
      • 去找Tree红黑树类型的(JDK1.8)
  3. 估算存放集合的数据量有多大,不管是List仍是Map,它们实现动态增加,都是有性能消耗的。在初始集合的时候给出一个合理的容量会减小动态增加时的消耗~
  4. 使用泛型,避免在运行时出现ClassCastException
  5. 尽量使用Collections工具类,或者获取只读、同步或空的集合,而非编写本身的实现。它将会提供代码重用性,它有着更好的稳定性和可维护性

12、ArrayList集合加入1万条数据,应该怎么提升效率

ArrayList的默认初始容量为10,要插入大量数据的时候须要不断扩容,而扩容是很是影响性能的。所以,如今明确了10万条数据了,咱们能够直接在初始化的时候就设置ArrayList的容量

这样就能够提升效率了~

十3、总结

2018年4月15日17:14:03,上面找了一些面试题答了一下,感受不够过瘾呀。不少我以为比较重要的知识点我都没有找到对应的面试题(可能我搜索的能力太水了?)。

将这篇文章做为集合的总结篇,但以为没什么好写就回答一些面试题去了,找了一会面试题又以为不够系统。而这篇总结我又不想复制前面的章节总结到这里来。因而我决定画一个脑图来结束这篇文章

2018年4月15日19:31:33 画完啦!!!!!

须要更多脑图的同窗可关注公众号:Java3y,回复【脑图】便可~

若是文章有错的地方欢迎指正,你们互相交流。习惯在微信看技术文章,想要获取更多的Java资源的同窗,能够关注微信公众号:Java3y。谢谢支持了!但愿能多介绍给其余有须要的朋友

文章的目录导航zhongfucheng.bitcron.com/post/shou-j…

目前初步打算写多线程,大家以为怎么样呢?能够在评论区留言~

相关文章
相关标签/搜索