集合框架的说明

  1. ArrayList 和 Vector 的区别。
    这两个类都实现了 List 接口(List 接口继承了 Collection 接口),他们都是有序集
    合,即存储在这两个集合中的元素的位置都是有顺序的,至关于一种动态的数组,我
    们之后能够按位置索引号取出某个元素,而且其中的数据是容许重复的,这是
    HashSet 之类的集合的最大不一样处,HashSet 之类的集合不能够按索引号去检索其
    中的元素,也不容许有重复的元素(原本题目问的与 hashset 没有任何关系,但为了
    说清楚 ArrayList 与 Vector 的功能,咱们使用对比方式,更有利于说明问题)。接
    着才说 ArrayList 与 Vector 的区别,这主要包括两个方面。

 同步性:
Vector 是线程安全的,也就是说是它的方法之间是线程同步的,而 ArrayList 是线
程序不安全的,它的方法之间是线程不一样步的。若是只有一个线程会访问到集合,那
最好是使用 ArrayList,由于它不考虑线程安全,效率会高些;若是有多个线程会访问
到集合,那最好是使用 Vector,由于不须要咱们本身再去考虑和编写线程安全的代
码。java

备注:对于 Vector&ArrayList、Hashtable&HashMap,要记住线程安全的问题,
记住 Vector 与 Hashtable 是旧的,是 java 一诞生就提供了的,它们是线程安全
的,ArrayList 与 HashMap 是 java2 时才提供的,它们是线程不安全的。因此,我
们讲课时先讲老的。编程

 数据增加:
ArrayList 与 Vector 都有一个初始的容量大小,当存储进它们里面的元素的个数超
过了容量时,就须要增长 ArrayList 与 Vector 的存储空间,每次要增长存储空间
时,不是只增长一个存储单元,而是增长多个存储单元,每次增长的存储单元的个数
在内存空间利用与程序效率之间要取得必定的平衡。Vector 默认增加为原来两倍,而
ArrayList 的增加策略在文档中没有明确规定(从源代码看到的是增加为原来的 1.5
倍)。ArrayList 与 Vector 均可以设置初始的空间大小,Vector 还能够设置增加的
空间大小,而 ArrayList 没有提供设置增加空间的方法。
总结:即 Vector 增加原来的一倍,ArrayList 增长原来的 0.5 倍。数组

  1. 说说 ArrayList,Vector, LinkedList 的存储性能和特性。
    ArrayList 和 Vector 都是使用数组方式存储数据,此数组元素数大于实际存储的数
    据以便增长和插入元素,它们都容许直接按序号索引元素,可是插入元素要涉及数组
    元素移动等内存操做,因此索引数据快而插入数据慢,Vector 因为使用了
    synchronized 方法(线程安全)。
    一般性能上较 ArrayList 差,而 LinkedList 使用双向链表实现存储,按序号索引数
    据须要进行前向或后向遍历,可是插入数据时只须要记录本项的先后项便可,因此插
    入速度较快 。
    ArrayList 在查找时速度快,LinkedList 在插入与删除时更具优点.安全

  2. 快速失败 (fail-fast) 和安全失败 (fail-safe) 的区别是什么?
    Iterator 的安全失败是基于对底层集合作拷贝,所以,它不受源集合上修改的影响。
    java.util 包下面的全部的集合类都是快速失败的,而 java.util.concurrent 包下面的
    全部的类都是安全失败的。快速失败的迭代器会抛出
    ConcurrentModificationException 异常,而安全失败的迭代器永远不会抛出这样的
    异常。数据结构

  3. hashmap 的数据结构。
    在 java 编程语言中,最基本的结构就是两种,一个是数组,另一个是模拟指针
    (引用),全部的数据结构均可以用这两个基本结构来构造的,hashmap 也不例
    外。Hashmap 其实是一个数组和链表的结合体(在数据结构中,通常称之为 “链
    表散列 “)
    enter image description here框架

  4. HashMap 的工做原理是什么?
    Java 中的 HashMap 是以键值对 (key-value) 的形式存储元素的。HashMap 须要
    一个 hash 函数,它使用 hashCode()和 equals()方法来向集合 / 从集合添加和检
    索元素。当调用 put() 方法的时候,HashMap 会计算 key 的 hash 值,而后把键
    值对存储在集合中合适的索引上。 若是 key 已经存在了,value 会被更新成新值。
    HashMap 的一些重要的特性是它的容量 (capacity),负载因子 (load factor) 和扩
    容极限(threshold resizing)。编程语言

  5. Hashmap 何时进行扩容呢?
    当 hashmap 中的元素个数超过数组大小 loadFactor 时,就会进行数组扩容,
    loadFactor 的默认值为 0.75,也就是说,默认状况下,数组大小为 16,那么当
    hashmap 中元素个数超过 160.75=12 的时候,就把数组的大小扩展为 216=32,
    即扩大一倍,而后从新计算每一个元素在数组中的位置,而这是一个很是消耗性能的操
    做,因此若是咱们已经预知 hashmap 中元素的个数,那么预设元素的个数可以有效
    的提升 hashmap 的性能。好比说,咱们有 1000 个元素 new HashMap(1000),
    可是理论上来说 new HashMap(1024) 更合适,不过上面 annegu 已经说过,即便
    是 1000,hashmap 也自动会将其设置为 1024。 可是 new HashMap(1024) 还
    不是更合适的,由于 0.751000 < 1000, 也就是说为了让 0.75 size > 1000, 咱们
    必须这样 new HashMap(2048) 才最合适,既考虑了 & 的问题,也避免了 resize
    的问题。ide

  6. List、Map、Set 三个接口,存取元素时,各有什么特色?
    这样的题属于随意发挥题:这样的题比较考水平,两个方面的水平:一是要真正明白
    这些内容,二是要有较强的总结和表述能力。若是你明白,但表述不清楚,在别人那
    里则等同于不明白。
    首先,List 与 Set 具备类似性,它们都是单列元素的集合,因此,它们有一个功共同
    的父接口,叫 Collection。Set 里面不容许有重复的元素,所谓重复,即不能有两个
    相等(注意,不是仅仅是相同)的对象 ,即假设 Set 集合中有了一个 A 对象,如今
    我要向 Set 集合再存入一个 B 对象,但 B 对象与 A 对象 equals 相等,则 B 对
    象存储不进去,因此,Set 集合的 add 方法有一个 boolean 的返回值,当集合中
    没有某个元素,此时 add 方法可成功加入该元素时,则返回 true,当集合含有与某
    个元素 equals 相等的元素时,此时 add 方法没法加入该元素,返回结果为 false。
    Set 取元素时,无法说取第几个,只能以 Iterator 接口取得全部的元素,再逐一遍历
    各个元素。

List 表示有前后顺序的集合, 注意,不是那种按年龄、按大小、按价格之类的排序。
当咱们屡次调用 add(Obj e) 方法时,每次加入的对象就像火车站买票有排队顺序一
样,按先来后到的顺序排序。有时候,也能够插队,即调用 add(int index,Obj e) 方
法,就能够指定当前对象在集合中的存放位置。一个对象能够被反复存储进 List 中,
每调用一次 add 方法,这个对象就被插入进集合中一次,其实,并非把这个对象
自己存储进了集合中,而是在集合中用一个索引变量指向这个对象,当这个对象被
add 屡次时,即至关于集合中有多个索引指向了这个对象,如图 x 所示。List 除了
能够以 Iterator 接口取得全部的元素,再逐一遍历各个元素以外,还能够调用
get(index i) 来明确说明取第几个。函数

Map 与 List 和 Set 不一样,它是双列的集合,其中有 put 方法,定义以下:
put(obj key,obj value),每次存储时,要存储一对 key/value,不能存储重复的
key,这个重复的规则也是按 equals 比较相等。取则能够根据 key 得到相应的
value,即 get(Object key) 返回值为 key 所对应的 value。另外,也能够得到全部
的 key 的结合,还能够得到全部的 value 的结合,还能够得到 key 和 value 组合
成的 Map.Entry 对象的集合。性能

List 以特定次序来持有元素,可有重复元素。Set 没法拥有重复元素, 内部排序。
Map 保存 key-value 值,value 可多值。

HashSet 按照 hashcode 值的某种运算方式进行存储,而不是直接按 hashCode
值的大小进行存储。例如,"abc" ---> 78,"def" ---> 62,"xyz" ---> 65 在hashSet 中的存储顺序不是 62,65,78,这些问题感谢之前一个叫崔健的学员提出,
最后经过查看源代码给他解释清楚,看本次培训学员当中有多少能看懂源码。

LinkedHashSet 按插入的顺序存储,那被存储对象的 hashcode 方法还有什么做用
呢?学员想一想! hashset 集合比较两个对象是否相等,首先看 hashcode 方法是否相
等,而后看 equals 方法是否相等。new 两个 Student 插入到 HashSet 中,看
HashSet 的 size,实现 hashcode 和 equals 方法后再看 size。

同一个对象能够在 Vector 中加入屡次。往集合里面加元素,至关于集合里用一根绳
子链接到了目标对象。往 HashSet 中却加不了屡次的。

  1. Set 里的元素是不能重复的,那么用什么方法来区分重复与否呢? 是用 == 仍是
    equals()? 它们有何区别?

Set 里的元素是不能重复的,元素重复与否是使用 equals() 方法进行判断的。
equals() 和 == 方法决定引用值是否指向同一对象 equals() 在类中被覆盖,为的是
当两个分离的对象的内容和类型相配的话,返回真值。

  1. 两个对象值相同 (x.equals(y) == true),但却可有不一样的 hash code,这句话对不对?
    对。若是对象要保存在 HashSet 或 HashMap 中,它们的 equals 相等,那么,它
    们的 hashcode 值就必须相等。
    若是不是要保存在 HashSet 或 HashMap,则与 hashcode 没有什么关系了,这时
    候 hashcode 不等是能够的,例如 arrayList 存储的对象就不用实现 hashcode,当
    然,咱们没有理由不实现,一般都会去实现的。

  2. heap 和 stack 有什么区别。
    Java 的内存分为两类,一类是栈内存,一类是堆内存。栈内存是指程序进入一个方法
    时,会为这个方法单独分配一块私属存储空间,用于存储这个方法内部的局部变量,
    当这个方法结束时,分配给这个方法的栈会释放,这个栈中的变量也将随之释放。
    堆是与栈做用不一样的内存,通常用于存放不放在当前方法栈中的那些数据,例如,使
    用 new 建立的对象都放在堆里,因此,它不会随方法的结束而消失。方法中的局部
    变量使用 final 修饰后,放在堆中,而不是栈中。

  3. Java 集合类框架的基本接口有哪些?
    集合类接口指定了一组叫作元素的对象。集合类接口的每一种具体的实现类均可以选
    择以它 本身的方式对元素进行保存和排序。有的集合类容许重复的键,有些不容许。
    Java 集合类提供了一套设计良好的支持对一组对象进行操做的接口和类。Java 集合
    类里面 最基本的接口有:
    Collection:表明一组对象,每个对象都是它的子元素。
    Set:不包含重复元素的 Collection。
    List:有顺序的 collection,而且能够包含重复元素。
    Map:能够把键 (key) 映射到值 (value) 的对象,键不能重复。
  4. HashSet 和 TreeSet 有什么区别?HashSet 是由一个 hash 表来实现的,所以,它的元素是无序的。add(),remove(),contains()
相关文章
相关标签/搜索