博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Java面试题——集合
阅读量:2428 次
发布时间:2019-05-10

本文共 2574 字,大约阅读时间需要 8 分钟。

集合相关概念

1.什么是集合

集合框架:用于存储数据的容器,集合框架是为表示和操作集合而规定的一种统一的标准的体系结构,集合包含三大块内容:

  1. 接口:表示集合的抽象数据类型
  2. 实现:集合接口的具体实现
  3. 算法:在一个实现了某个集合框架中的接口的对象身上完成某种有用的计算的方法

2.集合的特点

集合的特点主要有如下两点:

  1. 对象封装数据,集合用于存储对象
  2. 对象的个数确定可以使用数组,对象的个数不确定的可以用集合,因为集合是可变长度的

3.集合和数组的区别

  1. 数组可以存储基本数据类型和对象类型,集合只能存储对象类型
  2. 数组是固定长度的,但是集合是可变长度的
  3. 数组存储的元素必须是同一数据类型,集合存储的对象可以是不同数据类型(如Map集合中就可能存储了两种不同类型的数据)

4.常用的集合类有哪些

Map接口和Collection接口是所有集合框架的父接口

  1. Collection接口的子接口包括:Set接口和List接口,还有Queue接口。
    • Set是一个**无序(存入和取出的顺序有可能不一致)**容器,不可以存储重复元素,只允许存入一个null元素,必须保证元素的唯一性,其中Set接口的是实现类主要有:HashSet、TreeSet、LinkedHashSet
    • List接口是一个有序(先插入的在前,后插入的在后)容器,元素可以重复,可以插入多个null元素,元素都有索引。List接口的实现类主要有:ArrayList,LinkedList,Stack以及Vector
  2. Map是一个键值对集合,存储键、值和之间的映射Map接口的实现类主要有:HashMap、TreeMap、HashTable、ConcurrentHashMap以及Properties
    在这里插入图片描述
    在这里插入图片描述

5.哪些集合类是线程安全的

  • vector:就比ArrayList多了一个同步化机制(线程安全,即在迭代的过程中会更新最新的数据),不过效率低下,现在已经不太建议使用
  • statck:堆栈类,先进后出
  • hashtable:比hashmap多了一个线程安全
  • enumeration:枚举,相当于迭代器

6.Java集合的快速失败机制“fail-fast”

fail-fast机制,即快速失败机制,是Java集合中的一种错误检测机制。当在迭代集合过程中该集合在结构上发生改变的时候,就有可能发生fail-fast,即抛出ConcurrentModificationException异常

fail-fast原理:fail-fast是如何抛出ConcurrentModificationException异常的呢?我们知道,对于集合如list,map类,我们都可以通过迭代器来遍历,而iterator其实只是一个接口,如在ArrayList中,当调用list.iterator()时,其源码是:

public Iterator
iterator() { return new Itr(); }

即它会返回一个新的Itr类,而Itr类是ArrayList的内部类,实现了Iterator接口,其中在Itr类中有三个属性:

int cursor;int lastRet=-1;int expectedModCount=modCount;

其中cursor是指集合遍历过程中的即将遍历的元素的索引,lastRet等于cursor-1,默认为-1(表示不存在上一个时,为-1),expectedModCount就是快速失败机制的关键变量了,它初始值为ArrayList中的modCount(因为ArrayList是抽象类AbstractList中的子类,ArrayList也有这个变量,modCount用于记录集合操作过程中的修改次数

让我们看一下next()方法,看看为什么在迭代过程中,如果有线程对集合结构做出改变,就会发生fail-fast:
在这里插入图片描述
我们会发现,每次调用next()方法,在实际访问元素前,都会调用checkForComodification方法,该方法的源代码如下:
在这里插入图片描述
当modCount不等于expectedModCount时就会抛出异常,我们知道expectedModCount的默认初始值为modCount,它在遍历过程中不会在发生改变,所以有可能发生改变的只有modCount,当我们对集合进行add,remove,clear等涉及到集合中的元素个数的操作时,modCount就会发生改变,所以在遍历过程中,我们调用相关方法使集合个数发生改变,就会触发fail-fast异常
在这里插入图片描述
避免fail-fast的解决方案:

  1. 在单线程的遍历过程中,如果要进行remove操作,可以调用迭代器的remove方法,而不是集合类的remove方法
  2. 在遍历过程中,所有涉及到改变modCount值得地方全部加上synchronized。

7.迭代器Iterator是什么

Iterator接口提供遍历任何Collection的接口。我们可以从一个Collection中使用迭代器方法来获取迭代器实例,Iterator使用代码如下;

List
list=new ArrayList<>();Iterator
it=list.iterator();

迭代器只能单向遍历,但是更加安全,因为它可以确保,在当前遍历的集合元素被更改的时候,就会抛出ConcurrentModificationException异常

8.如何边遍历边移除Collection中的元素

边遍历边修改Collection的唯一正确方法是使用迭代器提供的操作Iterator.remove()方法,不能使用Collection提供的remove方法,因为会触发fail-fast机制,抛出ConcurrentModificationExcepction异常

9.Iterator和ListIterator有什么区别

  • Iterator可以遍历Set和List集合,而ListIterator只能遍历List
  • Iterator只能单向遍历,ListIterator可以双向遍历
  • ListIterator实现了Iterator接口,然后添加了一些额外的功能

转载地址:http://umjmb.baihongyu.com/

你可能感兴趣的文章
漫画:如何给女朋友解释什么是适配器模式?
查看>>
程序员又迎来一个好消息! | 每日趣闻
查看>>
Mac 被曝存在恶意漏洞:黑客可随意调动摄像头,波及四百万用户!
查看>>
拒绝与其他码农一致!CSDN定制T让你成为最靓的仔
查看>>
程序员情商低?看完这 4 类程序员我懂了!
查看>>
《长安十二时辰》里你不能不知道的 IT 技术 | 每日趣闻
查看>>
程序员爬取 3 万条评论,《长安十二时辰》槽点大揭秘!
查看>>
一年参加一次就够,全新升级的 AI 开发者大会议程出炉!
查看>>
基于 XDanmuku 的 Android 性能优化实战
查看>>
基于嵌入式操作系统的物联网安全
查看>>
一个只有 99 行代码的 JS 流程框架
查看>>
移动周刊第 186 期:移动 App 客户端性能优化、iOS 开源库源码解析
查看>>
包学会之浅入浅出 Vue.js:开学篇
查看>>
JavaScriptCore 全面解析 (上篇)
查看>>
移动周刊第 187 期:App 模块化实战经验总结
查看>>
以不一样的视角看物联网协议
查看>>
JavaScriptCore全面解析 (下篇)
查看>>
嵌入式操作系统与物联网演进之路
查看>>
苹果公司揭秘首批列入 Swift 源代码兼容性开源项目清单
查看>>
Python 玩转物联网之 Micropython GPIO IRQ 处理
查看>>