美文网首页
Java集合面试题

Java集合面试题

作者: 行者和他的钢笔 | 来源:发表于2018-09-18 08:39 被阅读33次

    1、Iterator的并发修改异常

    运行代码时发生了错误 java.util.ConcurrentModificationException[并发修改异常]这是什么原因呢?

    在迭代过程中,使用了集合的方法对元素进行操作。导致迭代器并不知道集合中的变化,容易引发数据的不确定性。

    并发修改异常解决办法:在迭代时,不要使用集合的方法操作元素。

    那么想要在迭代时对元素操作咋办?通过ListIterator迭代器操作元素是可以的,ListIterator的出现,解决了使用Iterator迭代过程中可能会发生的错误情况。

    2、Java中三种长度表现形式

    数组.length 属性 返回值 int
    字符串.length() 方法,返回值int
    集合.size()方法, 返回值int

    3、 equals() 与 == 的区别是什么?

    == : 它的作用是判断两个对象的地址是不是相等。即,判断两个对象是不试同一个对象。

    equals() : 它的作用也是判断两个对象是否相等。但它一般有两种使用情况(前面第1部分已详细介绍过):
    情况1,类没有覆盖equals()方法。则通过equals()比较该类的两个对象时,等价于通过“==”比较这两个对象。
    情况2,类覆盖了equals()方法。一般,我们都覆盖equals()方法来两个对象的内容相等;若它们的内容相等,则返回true(即,认为这两个对象相等)。

    4、两个对象值相同(x.equals(y) == true),但却可有不同的hash code,这句话对不对?

    Java对于eqauls方法和hashCode方法是这样规定的:
    (1)如果两个对象相同(equals方法返回true),那么它们的hashCode值一定要相同;
    (2)如果两个对象的hashCode相同,它们并不一定相同。

    hashCode() 的作用是获取哈希码,也称为散列码;它实际上是返回一个int整数。这个哈希码的作用是确定该对象在哈希表中的索引位置。

    哈希冲突:不同的键值对,哈希值相等

    hashCode() 定义在JDK的Object.java中,这就意味着Java中的任何类都包含有hashCode() 函数。但是只有在HashSet, Hashtable, HashMap等等这些本质是散列表的数据结构中,这个方法才有用

    eqauls方法
    Object.java中定义了equals()方法,这就意味着所有的Java类都实现了equals()方法,此时定义的equals()方法的功能与“==”一样,都是根据地址判断是否是同一个对象。

    当我们对equals()方法进行重写之后,equals()方法的功能就是判断两个对象的内容是否相等。相等返回true

    “==”一直都是根据地址判断两个对象是否相等

    5、数据存储常用结构

    堆栈、队列、数组、链表

    堆栈:先进后出,栈的出口入口都是栈的顶端

    队列:先进先出,队列的入口、出口各占一列

    数组:查找元素快(通过索引),增删元素慢(都需要创建新数组然后进行增加和删除操作)

    链表:多个节点通过地址进行连接
    查找元素慢,添加元素快

    6、Collection 、Collections、List、Set的区别

    List与Set都继承于Collection,Collection是集合的顶级接口。而Collections是集合工具类。
    list为有序集合接口,ArrayList、LinkedList、Vector为其实现类;

    Set是无序不重复集合接口,HashSet、LinkedHashSet、TreeSet为其实现类

    7、ArrayList、LinkedList、Vector的区别【List有序集合】

    list为有序集合接口,ArrayList、LinkedList、Vector为其实现类;

    ArrayList和 Vector:底层为数组、查询快、增删慢 。
    ArrayList :底层为数组、查询快、增删慢 。由于开发中最多的功能就是查询数据、遍历数据,所以ArrayList是最常用的集合。效率高、线程不安全;

    Vector:底层为数组、查询快、增删慢 。效率低、线程安全。线程安全的原因:使用了synchronize进行同步写数据,但是开销比较大,所以vector是一个同步容器并不是一个并发容器。

    LinkedList:底层为链表结构、查询慢、增删快。【LinkedList插入,删除都是移动指针效率很高;
    查找需要进行遍历查询,效率较低】

    8、哈希表

    什么是哈希表呢?

    哈希表底层使用的也是数组机制,数组中也存放对象,而这些对象往数组中存放时的位置比较特殊,当需要把这些对象给数组中存放时,那么会根据这些对象的特有数据结合相应的算法,计算出这个对象在数组中的位置,然后把这个对象存放在数组中。而这样的数组就称为哈希数组,即就是哈希表。
    当向哈希表中存放元素时,需要根据元素的特有数据结合相应的算法,这个算法其实就是Object类中的hashCode方法。由于任何对象都是Object类的子类,所以任何对象有拥有这个方法。即就是在给哈希表中存放对象时,会调用对象的hashCode方法,算出对象在表中的存放位置,这里需要注意,如果两个对象hashCode方法算出结果一样,这样现象称为哈希冲突,这时会调用对象的equals方法,比较这两个对象是不是同一个对象,如果equals方法返回的是true,那么就不会把第二个对象存放在哈希表中,如果返回的是false,就会把这个值存放在哈希表中。
    【算法计算出来的数据是这个对象在数组中存放的位置。。。。。由于是set集合,元素是不重复的,所以当两个对象---这里的两个对象肯定是不相同的----哈希值相同时,称之为哈希冲突,这个时候会调用对象的】
    总结:保证HashSet集合元素的唯一,其实就是根据对象的hashCode和equals方法来决定的。如果我们往集合中存放自定义的对象,那么保证其唯一,就必须复写hashCode和equals方法建立属于当前对象的比较方式。

    说重点
    简单叙述哈希表结构存储数据的原理:

    哈希表底层使用的是数组机制,数组中存放对象。这些对象的存放位置有些特殊。

    当我们向哈希表中存放元素的时候,需要根据特有的数据结合hashCode()方法计算出这个对象在数组中的存放位置

    注意:如果两个对象hashCode()方法算出的结果一样,这种现象称之为哈希冲突。这个时候会调用对象的equals()方法,比较这两个对象是不是同一个对象,如果equals()方法返回的是true,那么就不会把第二个对象存放在哈希表中,如果返回的是false,就会把这个值存放在哈希表中

    哈希表结构存储数据原理

    9、HashSet、LinkedHashSet、TreeSet

    Set是无序不重复集合接口,HashSet、LinkedHashSet、TreeSet为其实现类

    HashSet底层结构是哈希表结构,元素唯一不能重复。(如何保证元素的唯一性:重写hashCode()与equals()方法)【hashSet原理比较简单,几乎全部借助于hashMap来实现的。所以HashMap会出现的问题HashSet依然不能避免】

    LinkedHashSetHashSet的一个子类,底层存储结构式链表和哈希表组合,保证元素的唯一性和有序性。(元素的存与取得顺序一致)

    10、判断集合元素唯一的原理

    10.1、ArrayList的contains()方法判断元素是否重复原理

    ArrayList的contains()方法会使用调用方法时,传入的元素的equals方法依次与集合中的旧元素所比较,从而根据返回的布尔值判断是否有重复元素。此时,当ArrayList存放自定义类型时,由于自定义类型在未重写equals方法前,判断是否重复的依据是地址值,所以如果想根据内容判断是否为重复元素,需要重写元素的equals方法。
    注意:List集合可以存放重复元素,所以ArrayList的contains()方法会使用调用方法时,传入的元素的equals()方法依次与集合中的旧元素所比较,从而根据返回的布尔值判断是否有重复元素。

    10.2、HashSet的add/contains等方法判断元素是否重复原理

    注意:Set集合元素不能重复,所以contains()不行。需要重写hashCode()方法和equals()方法

    11、Map接口

    11.1、Map接口中的常用方法

    11.2、Map集合遍历方式

    方式一:Map集合遍历键找值方式


    代码实现
    方式二:Map集合遍历键值对方式 Entry键值对对象 遍历键找值 代码实现
    注意:两种方式对比建议使用遍历键值对找值。因为遍历键值对找值可以把key,value同时取出,使用遍历键找值还需要通过key取一次value,效率较低

    12、HashMap、HashTable


    Map集合元素都是以键值对的形式存取
    键不能重复,值可以重复

    12.1、HashMap:

    特点:
    是Map集合的子集合
    底层基于数组和链表实现的
    HashMap集合中的key不能重复,通过重写hashCode() 与 equals()方法来保证键的唯一。
    不能保证元素存与取的顺序完全一致
    HashMap的效率高、线程不安全、允许键或值为空
    注意:在并发情况下使用hashMap容易出现死循环(并发情况下发生扩容时会出现环形链表)。并发场景发生扩容的时候,所以hashMap只能在单线程中使用

    重点

    由于hashMap是一个线程不安全的容器,主要是当容量发生扩容的时候会出现环形链表从而导致死循环。(当容量大于总量*负载因子时)
    因此需要支持线程安全的并发容器
    ConcurrentHashMap

    12.2、 LinkedHashMap

    LinkedHashMap:
    特点:
    是HashMap集合的子集合
    底层采用哈希表+链表结构
    LinkedHashMap集合中的key不能重复,通过重写hashCode() 与 equals()方法来保证键的唯一。

    HashMap、HashTable
    HashMap的效率高、线程不安全、允许键或值为空
    HashTable线程安全、效率低、不允许键或值为空

    相关文章

      网友评论

          本文标题:Java集合面试题

          本文链接:https://www.haomeiwen.com/subject/pxmxmftx.html