前言

声明,本文用的是jdk1.8

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

回顾目录:

Java容器可分为两大类:

  • Collection

    • List

      • ArrayList
      • LinkedList
      • Vector(了解,已过时)
    • Set
      • HashSet

        • LinkedHashSet
      • TreeSet
  • Map
    • HashMap

      • LinkedHashMap
    • TreeMap
    • ConcurrentHashMap
    • Hashtable(了解,,已过时)

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

其实,我也不知道要怎么总结好,因为之前写每一篇的时候都总结过了。现在又把他们重新罗列出来好像有点水,所以,我决定去回答一些Java容器的面试题!

当然了,我的答案未必就是正确的。如果有错误的地方大家多多包含,希望不吝在评论区留言指正~~

一、ArrayList和Vector的区别

共同点:

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

区别:

  • 同步性:

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

二、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>

三、List和Map的区别

共同点:

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

不同点:

  • 存储结构不同

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

四、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()方法都有使用

五、Collection和Collections的区别

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

六、说出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要快。(我测试过)

七、Enumeration和Iterator接口的区别

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

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

区别有三点:

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

八、ListIterator有什么特点

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

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

九、并发集合类是什么?

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

  • 迭代器被设计为fail-fast的,会抛出ConcurrentModificationException。
  • 一部分类为:
    • CopyOnWriteArrayList
    • ConcurrentHashMap
    • CopyOnWriteArraySet

十、Java中HashMap的key值要是为类对象则该类需要满足什么条件?

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

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

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

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

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

  1. 根据需要确定集合的类型。如果是单列的集合,我们考虑用Collection下的子接口ArrayList和Set。如果是映射,我们就考虑使用Map~
  2. 确定完我们的集合类型,我们接下来确定使用该集合类型下的哪个子类~我认为可以简单分成几个步骤:
    • 是否需要同步

      • 去找线程安全的集合类使用
    • 迭代时是否需要有序(插入顺序有序)
      • 去找Linked双向列表结构的
    • 是否需要排序(自然顺序或者手动排序)
      • 去找Tree红黑树类型的(JDK1.8)
  3. 估算存放集合的数据量有多大,无论是List还是Map,它们实现动态增长,都是有性能消耗的。在初始集合的时候给出一个合理的容量会减少动态增长时的消耗~
  4. 使用泛型,避免在运行时出现ClassCastException
  5. 尽可能使用Collections工具类,或者获取只读、同步或空的集合,而非编写自己的实现。它将会提供代码重用性,它有着更好的稳定性和可维护性

十二、ArrayList集合加入1万条数据,应该怎么提高效率

ArrayList的默认初始容量为10,要插入大量数据的时候需要不断扩容,而扩容是非常影响性能的。因此,现在明确了10万条数据了,我们可以直接在初始化的时候就设置ArrayList的容量

这样就可以提高效率了~

十三、总结

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

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

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

需要更多脑图的同学可关注公众号:Java3y,回复【脑图】即可~

如果文章有错的地方欢迎指正,大家互相交流。习惯在微信看技术文章,想要获取更多的Java资源的同学,可以关注微信公众号:Java3y。为了大家方便,刚新建了一下qq群:742919422,大家也可以去交流交流。谢谢支持了!希望能多介绍给其他有需要的朋友

文章的目录导航https://zhongfucheng.bitcron.com/post/shou-ji/wen-zhang-dao-hang

目前初步打算写多线程,你们觉得怎么样呢?可以在评论区留言~

Java集合总结【面试题+脑图】,将知识点一网打尽!的更多相关文章

  1. Java集合框架面试题

    www.cnblogs.com/zhxxcq/archive/2012/03/11/2389611.html 这里的两个图很形象,由于放进图片链接,图片显示不了,所以只能给出该链接. Java集合框架 ...

  2. 50道Java集合经典面试题(收藏版)

    前言 来了来了,50道Java集合面试题也来啦~ 已经上传github: https://github.com/whx123/JavaHome 1. Arraylist与LinkedList区别 可以 ...

  3. java 集合 + 常见面试题

    1.1. 集合概述 1.1.1. Java 集合概览 从下图可以看出,在 Java 中除了以 Map 结尾的类之外, 其他类都实现了 Collection 接口. 并且,以 Map 结尾的类都实现了 ...

  4. 【面试题】Java集合部分面试题

    集合与数组? 数组:(可以存储基本数据类型)是用来存储对象的一种容器,但是数组的长度固定,不适合在对象数量未知的情况下使用 集合:(只能存储对象,对象类型可以不一样)集合的长度可变,可在多数情况下使用 ...

  5. Java集合常见面试题集锦

    1.介绍Collection框架的结构 集合是Java中的一个非常重要的一个知识点,主要分为List.Set.Map.Queue三大数据结构.它们在Java中的结构关系如下: Collection接口 ...

  6. 这几道Java集合框架面试题几乎必问

    Arraylist 与 LinkedList 异同 补充:数据结构基础之双向链表 ArrayList 与 Vector 区别 HashMap的底层实现 JDK1.8之前 JDK1.8之后 HashMa ...

  7. 这几道Java集合框架面试题在面试中几乎必问

    Arraylist 与 LinkedList 异同 1. 是否保证线程安全: ArrayList 和 LinkedList 都是不同步的,也就是不保证线程安全: 2. 底层数据结构: Arraylis ...

  8. java集合常见面试题

    1. Array和ArrayList的区别,什么时候更合适用Array a)      Array是数组,可以容纳基本类型和对象,而ArrayList是集合,只能容纳对象 b)      Array是 ...

  9. Java架构师技能发展脑图

    图中还有好多东西不会,先把图保存好,逐项击破

随机推荐

  1. 设计模式 --> (8)组合模式

    组合模式 组合模式,是为了解决整体和部分的一致对待的问题而产生的,要求这个整体与部分有一致的操作或行为.部分和整体都继承与一个公共的抽象类,这样,外部使用它们时是一致的,不用管是整体还是部分,使用一个 ...

  2. Algorithm --> 快速排序

    快速排序 算法思想 快速排序采用的思想是分治思想. 快速排序是找出一个元素(理论上可以随便找一个)作为基准(pivot),然后对数组进行分区操作,使基准左边元素的值都不大于基准值,基准右边的 元素值都 ...

  3. RESTful WebService 入门实例

      /* 新建MavenProject,使用以下代码,创建类和POM文件.使用命令行切换到Project根目录,运行mvn package(或者,选中pom.xml 文件右键单击 > run a ...

  4. PHP 环境搭建篇

    0x01 PHP 简介 PHP 是一种流行的通用脚本语言, 特别适合 web 开发. 快速, 灵活, 务实, PHP 的所有东西, 从你的博客到世界上最流行的网站. 0x02 PHP环境要求 Tips ...

  5. 发布利用 Qt Assistant来做帮助系统的程序遇到的问题

    最近,一直在做反演初始模型可视化建模的软件 model Constraint,最后的步骤就是利用 Qt Assistant为自己的程序制作帮助系统. 1.<Qt Creator快速入门>和 ...

  6. DirectSound---捕获音频、Qml/C++ 集成交互

    DirectSound的音频捕获原理和播放原理差不多,内部在一个缓冲区上循环写入捕获到的数据,并且提供notify通知功能. 1. 音频捕获 因为捕获流程和播放流程类似,我们就不在这里赘述了,只给出简 ...

  7. Java读取文件存储到mysql

    写了一批Lua脚本,要放到数据库里面,调用的时候进行计算,由于有太多lua脚本,就写了个程序来录入. 下面主要分三个部分: public static String readToString(Stri ...

  8. 异步协程 的 trip库

    import trip headers = { 'User-Agent':'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, ...

  9. java中<> 的用法

    泛型是Java SE 1.5的新特性,泛型的本质是参数化类型,也就是说所操作的数据类型被指定为一个参数.这种参数类型可以用在类.接口和方法的创建中,分别称为泛型类.泛型接口.泛型方法. Java语言引 ...

  10. 去掉xcode编译warning:ld: warning: directory not found for option '-L

    选择工程, 编译的 (targets) 选择 Build Settings 菜单 查找 Library Search Paths 和 Framework Search Paths, 删掉编译报warn ...