1.Java中集合框架图

2.List 和 Set 的区别?

  1. List , Set 都是继承自Collection 接口

  2. List 特点:一个有序(元素存入集合的顺序和取出的顺序一致)容器,元素可以重复,可以插入多个null元素,元素都有索引。常用的实现类有 ArrayList、LinkedList 和 Vector。

  3. Set 特点:一个无序(存入和取出顺序有可能不一致)容器,不可以存储重复元素,只允许存入一个null元素,必须保证元素唯一性。Set 接口常用实现类是HashSet、LinkedHashSet 以及 TreeSet。

  4. List 支持for循环遍历,也可以用迭代器,但是set只能用迭代,因为它是无序的,所以无法用下标来取得想要的值。

  5. Set和List对比
    Set:检索元素效率低下,删除和插入效率高,插入和删除不会引起元素位置改变。
    List:和数组类似,List可以动态增长,查找元素效率高,插入删除元素效率低,因为会引起其他元素位置改变

3.为什么HashMap中String、Integer这样的包装类适合作为key?

  1. String、Integer等包装类的特性能够保证Hash值的不可更改性和计算准确性,能够有效的减少Hash碰撞的几率。内部已重写了equals()、hashCode()等方法,遵守了HashMap内部的规范,不容易出现Hash值计算错误的情况。
  2. 都是final类型,即不可变性,保证key的不可更改性,不会存在获取 hash值不同的情况。

4.ArrayList的优缺点?

  1. ArrayList的优点如下:
    ArrayList 底层以数组实现,是一种随机访问模式。ArrayList 实现了 RandomAccess 接口,因此查找的时候非常快。
    ArrayList 在顺序添加一个元素的时候非常方便。
  2. ArrayList 的缺点如下:
    删除元素的时候,需要做一次元素复制操作。如果要复制的元素很多,那么就会比较耗费性能。
    插入元素的时候,也需要做一次元素复制操作,缺点同上。
  3. ArrayList适合使用的场景
    ArrayList 比较适合顺序添加、随机访问的场景。

5.ArrayList 和 Vector 的区别是什么?

  1. ArrayList和Vector都实现了List 接口,List 接口继承了 Collection 接口,它们都是有序集合

  2. 线程安全:Vector 使用了 Synchronized 来实现线程同步,是线程安全的,而 ArrayList 是非线程安全的。

  3. 性能效率:因为是否加锁会影响效率,所有不加锁的ArrayList 在性能方面要优于加锁的Vector。

  4. 扩容机制:ArrayList 和 Vector 都会根据实际的需要动态的调整容量,只不过在Vector 扩容每次会增加 1 倍,而 ArrayList 只会增加 50%。

  5. Vector类的所有方法都是同步的。可以由两个线程安全地访问一个Vector对象、但是一个线程访问Vector的话代码要在同步操作上耗费大量的时间。Arraylist不是同步的,所以在不需要保证线程安全时时建议使用Arraylist。

6.HashMap 的长度为什么是2的幂次方?

  1. 为什么HashMap的长度是2的幂次方?
    为了能让 HashMap 存取高效,尽量较少碰撞,也就是要尽量把数据分配均匀,每个链表/红黑树长度大致相同。这个实现就是把数据存到哪个链表/红黑树中的算法。

  2. 这个算法应该如何设计呢?或者说这个算法该怎么实现呢?
    我们首先可能会想到采用%取余的操作来实现。重点来了:“取余(%)操作中如果除数是2的幂次则等价于与其除数减一的与(&)操作(也就是说hash%length==hash&(length-1)的前提是 length 是2的 n 次方;)。” 最后我们HashMap底层采用的就是通过二进制位操作 &,相对于%能够提高运算效率,这就解释了 HashMap 的长度为什么是2的幂次方。

  3. 那为什么是两次扰动呢?(jdk1.8源码)
    加大哈希值低位的随机性,使得分布更均匀,从而提高对应数组存储下标位置的随机性&均匀性, 最终减少Hash冲突,两次就够了,已经达到了高位低位同时参与运算的目的。

在JDK 1.7中,更为简洁,相比在1.7中的4次位运算,5次异或运算(9次扰动),在1.8中,只进行了1次位运算和1次异或运算(2次扰动)

7. 能否使用任何类作为 Map 的 key?

  1. 可以使用任何类作为 Map 的 key,然而在使用之前,需要考虑以下几点: 如果类重写了 equals() 方法,也应该重写 hashCode() 方法。类的所有实例需要遵循与 equals() 和 hashCode() 相关的规则。如果一个类没有使用 equals(),不应该在 hashCode() 中使用它。

  2. 用户自定义 Key 类的最佳实践是使之为不可变的,也就是需要通过final关键字来修饰,这样 hashCode() 值可以被缓存起来,拥有更好的性能。不可变的类也可以确保 hashCode() 和 equals() 在未来不会改变,这样就会解决与可变相关的问题了。

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

  1. fail-fast是java集合的一种错误检测机制,当多个线程对集合进行结构上的改变的操作时,有可能会产生 fail-fast 机制。
  2. 实操案例:
    例如:假设存在两个线程(线程1、线程2),线程1通过Iterator在遍历集合A中 的元素,在某个时候线程2修改了集合A的结构(是结构上面的修改,而不是简单的修改集合元素的内容),那么这个时候程序就会抛出ConcurrentModificationException 异常,从而产生fail-fast机制。
  3. 原因解析:迭代器在遍历时直接访问集合中的内容,并且在遍历过程中使用一个 modCount 变量。集合在被遍历期间如果内容发生变化,就会改变modCount 的值。每当迭代器使用hashNext()/next()遍历下一个元素之前,都会检测 modCount变量是否为expectedmodCount值,是的话就返回遍历;否则抛出 异常,终止遍历。
  4. 解决办法:
    方法1:在遍历过程中,所有涉及到改变modCount值得地方全部加上 synchronized。
    方法2:使用CopyOnWriteArrayList来替换ArrayList

9.Iterator 和 ListIterator 有什么区别?

  1. Iterator 可以遍历 Set 和 List 集合,而 ListIterator 只能遍历 List。

  2. Iterator 只能单向遍历,而 ListIterator 可以双向遍历(向前/后遍历)。

  3. ListIterator 实现 Iterator 接口,然后添加了一些额外的功能,比如添加一个元 素、替换一个元素、获取前面或后面元素的索引位置。

10.为什么 ArrayList 的 elementData 加上 transient 修饰?

  1. ArrayList 中的数组定义如下:
    transient 的作用是说不希望 elementData 数组被序列化,重写了 writeObject 实现
  private transient Object[] elementData;
  1. 再看一下 ArrayList 的定义:
    可以看到 ArrayList 实现了 Serializable 接口,这意味着 ArrayList 支持序列化。
public class ArrayList<E> extends AbstractList<E> implements List<E>, RandomAccess, Cloneable, java.io.Serializable
  1. 每次序列化时,先调用 defaultWriteObject() 方法序列化 ArrayList 中的非transient 元素,然后遍历 elementData,只序列化已存入的元素,这样既加快了序列化的速度,又减小了序列化之后的文件大小。
  2. 底层实操代码:
    ArrayList在序列化的时候会调用writeObject,直接将size和element写入ObjectOutputStream;
/*** Save the state of the <tt>ArrayList</tt> instance to a stream (that* is, serialize it).** @serialData The length of the array backing the <tt>ArrayList</tt>*             instance is emitted (int), followed by all of its elements*             (each an <tt>Object</tt>) in the proper order.*/
private void writeObject(java.io.ObjectOutputStream s)throws java.io.IOException{// Write out element count, and any hidden stuffint expectedModCount = modCount;s.defaultWriteObject();// Write out size as capacity for behavioural compatibility with clone()s.writeInt(size);// Write out all elements in the proper order.for (int i=0; i<size; i++) {s.writeObject(elementData[i]);}if (modCount != expectedModCount) {throw new ConcurrentModificationException();}
}

反序列化时调用readObject,从ObjectInputStream获取size和element,再恢复到elementData

/*** Reconstitute the <tt>ArrayList</tt> instance from a stream (that is,* deserialize it).*/
private void readObject(java.io.ObjectInputStream s)throws java.io.IOException, ClassNotFoundException {elementData = EMPTY_ELEMENTDATA;// Read in size, and any hidden stuffs.defaultReadObject();// Read in capacitys.readInt(); // ignoredif (size > 0) {// be like clone(), allocate array based upon size not capacityensureCapacityInternal(size);Object[] a = elementData;// Read in all elements in the proper order.for (int i=0; i<size; i++) {a[i] = s.readObject();}}
}

总结:为什么不直接用elementData来序列化,而采用上诉的方式来实现序列化呢?原因在于elementData是一个缓存数组,它通常会预留一些容量,等容量不足时再扩充容量,那么有些空间可能就没有实际存储元素,采用上诉的方式来实现序列化时,就可以保证只序列化实际存储的那些元素,而不是整个数组,从而节省空间和时间。

好了,关于【Java中常用的集合类–Java中集合框架图-List 和 Set 的区别-为什么HashMap中String、Integer这样的包装类适合作为key-ArrayList的优缺点-为什么 ArrayList 的 elementData 加上 transient 修饰?Iterator 和 ListIterator 有什么区别? Java集合的快速失败机制 “fail-fast”? 能否使用任何类作为 Map 的 key?HashMap 的长度为什么是2的幂次方?】就先学习到这里,更多的内容持续创作学习中。

【Java中常用的集合类】相关推荐

  1. Java中常用的类,包,接口

    Java中常用的类,包,接口 包名 说明 java.lang 该包提供了Java编程的基础类,例如 Object.Math.String.StringBuffer.System.Thread等,不使用 ...

  2. java高级特性2_Java高级特性 第2节 java中常用的实用类(1)

    一.Java API Java API即Java应用程序编程接口,他是运行库的集合,预先定义了一些接口和类,程序员可以直接调用:此外也特指API的说明文档,也称帮助文档. Java中常用的包: jav ...

  3. java 中常用的类

    java 中常用的类 Math Math 类,包含用于执行基本数学运算的方法 常用API 取整 l  static double abs(double  a) 获取double 的绝对值 l  sta ...

  4. 动图 + 源码,演示 Java 中常用数据结构执行过程及原理

    最近在整理数据结构方面的知识, 系统化看了下Java中常用数据结构, 突发奇想用动画来绘制数据流转过程. 主要基于jdk8, 可能会有些特性与jdk7之前不相同, 例如LinkedList Linke ...

  5. java中常用的几种排序算法--常见笔试面试

    转载:http://blog.csdn.net/ygc87/article/details/7208082 以下列出Java中常用的几种排序算法,只是简单实现了排序的功能,还有待改进,望指教(以下均假 ...

  6. 数据结构中缀表达式转后缀表达式与后缀表达式的求值实训报告_动图+源码,演示 Java 中常用数据结构执行过程及原理...

    程序员的成长之路互联网/程序员/成长/职场 关注 阅读本文大概需要 3.7 分钟. 作者:大道方圆cnblogs.com/xdecode/p/9321848.html 最近在整理数据结构方面的知识, ...

  7. JAVA中常用的逻辑运算符_Java中常用的运算符

    运算符是一种"功能"符号,用以通知 Java 进行相关的运算,Java 语言中常用的运算符可分为如下几种: 算数运算符.赋值运算符.比较运算符.逻辑运算符.条件运算符. 一.算数运 ...

  8. java中常用的包、类、以及包中常用的类、方法、属性----sql和text\swing

    java中常用的包.类.以及包中常用的类.方法.属性 常用的包 java.io.*; java.util.*; java.lang.*; java.sql.*; java.text.*; java.a ...

  9. java中常用API、Scanner类、匿名对象、Random类、ArrayList类、对象数组

    java中常用API: API:Application Programming Interface,应用程序编程接口.Java API是JDK中提供给我们使用的类的说明文档.这些类将底层的代码实现封装 ...

最新文章

  1. 【c语言】蓝桥杯算法提高 填充蛋糕
  2. CVPR 2021 | 港科大:如何利用闪光图像(flash image)来去除反光
  3. 极客青年说,北京沙龙
  4. 带负荷测试要求二次最小电流_开关柜设计人员如何选择合适的零序电流互感器?...
  5. 尚硅谷_springcloud(2020新版 思维导图_全网最火SpringCloud2020全家桶教程
  6. 来客推仿拼多多电商商城小程序源码
  7. android仿今日头条App、多种漂亮加载效果、选择器汇总、记事本App、Kotlin开发等源码...
  8. diskpart 设置硬盘格式
  9. 「架构师必备」java程序员面试宝典百度云
  10. 君澜酒店集团与来也股份合作,打造国内“冰雪度假打卡圣地”
  11. NLP - 结巴分词 词云
  12. 虚拟机Ubuntut tftp服务不启动,service tftpd-hpa restart 失败的处理
  13. Oracle EBS流程之--PO ER Model
  14. 20155314 2016-2017-2 《Java程序设计》第4周学习总结
  15. 迷宫问题的求解(广度和深度优先搜索)
  16. mysql uuid分页优化_MySQL性能优化之分页查询优化
  17. MiniGUI学习整理
  18. php dateparse,PHP date_parse_from_format() 函数用法及示例
  19. Tomcat的安装与启动
  20. MyBatis总结 Day01

热门文章

  1. 京东开普勒导购模式代码分享[java]
  2. 有时候 遗憾也未尝不是一种美
  3. 云上有为 · 未来无界 | 2021上海站 ECUG Con 第一天回忆录
  4. 计算机驱动恢复出厂设置在哪里,电脑、手机如何恢复出厂设置?
  5. Ubuntu下使用Anaconda3 出现conda: 未找到命令
  6. 解决VMware虚拟机,ens33网卡丢失
  7. 网易面试题:男女小孩战队问题
  8. 张小龙1.5万字最新演讲:微信十周年,回答一切
  9. ueditor多图片上传中去掉在线管理和图片搜索Tab页功能
  10. python爬取王者_python爬取王者荣耀全皮肤的简单实现代码