抱歉,您的瀏覽器無法訪問本站
本頁面需要瀏覽器支持(啟用)JavaScript
了解詳情 >

JDK1.8中HashMap在出现hash碰撞时链表长度超过8一定会变成红黑树?

首先答案是:否,因为实际上转换红黑树有个大前提,就是当前hash table的长度也就是HashMap的capacity(不是size)不能小于64.小于64就只是做个扩容。

HashSet和TreeSet的区别

底层数据结构 顺序 存放null值
HashSet 哈希表 无序 能够存放一个null值
TreeSet 二叉树 有序;分为自然排序和定制排序 不能够存放null值

HashSet的底层原理

HashSet的底层就是在HashMap的基础上包装了一层,只不过存储的时候的value是默认存储了一个Object的静态常量,存取都是使用key。

LinkedHashMap底层原理

LinkedHashMap通过维护一个运行于所有条目的双向链表,保证了集合元素迭代的顺序,这个顺序可以是插入顺序或者访问顺序。

LinkedHashMap可以看作是HashMap和LinkedList的集合,它使用HashMap来存储数据,使用LinkedList来维护顺序。

为什么集合类没有实现Cloneable和Serializable接口

克隆(cloning)或者序列化(serialization)的语义和含义是跟具体的实现相关的。因此应该由集合类的具体实现类来决定如何被克隆或者序列化

Iterator和ListInterator的区别

ListIterator 继承 Iterator

ListIterator 比 Iterator多方法

  • 使用范围不同,Iterator可以迭代所有集合;ListIterator 只能用于List及其子类
  • ListIterator 有 add 方法,可以向 List 中添加对象;Iterator 不能
  • ListIterator 有 hasPrevious() 和 previous() 方法,可以实现逆向遍历;Iterator不可以
  • ListIterator 有 nextIndex() 和previousIndex() 方法,可定位当前索引的位置;Iterator不可以
  • ListIterator 有 set()方法,可以实现对 List 的修改;Iterator 仅能遍历,不能修改

Collection和Collections的区别

  • java.util.Collection是一个顶层集合接口,它定义了对集合对象的基本操作的通用方法
  • java.util.Collections是一个工具类,它提供了一系列静态方法,用于对集合进行排序、搜索、创建线程集合等操作

如何实现数组和 List 之间的转换?

数组转List使用:Arrays.asList()。

List转数组使用:list.toArray()和list.toArray(数组类型),例如:list.toArray(new String[0])

ArrayList 和 Vector 的区别是什么?

Vector使用了Synchronized实现了线程安全,但效率就变得很慢,同时Vector在每扩容的时候会每次增加一倍。

ArrayList是线程不安全的,但效率就会比Vector快的多,同时ArrayList每次增加50%。

Array 和 ArrayList 有何区别?

Array最高效但容量初始化时就固定了且无法动态改变。

ArrayList容量可以动态增加,但牺牲了效率,同时不能够存放基本类型。

Queue中的方法们不同点是啥?

offer()和add()

两个方法都是再往队列里面添加一个元素、但在队列已经满了的时候,调用 add方法就会抛出一个unchecked异常调用offer方法就返回一个false

peek()和element()

两个方法都是在不移除的情况下返回当前头部的元素、但在队列为空的情况下,调用 element方法就会抛出一个NoSuchElementException异常调用peek方法就返回null

poll()和remove()

两个方法都是移除当前的头部元素、但是在队列为空的情况下,调用remove()方法就会抛出一个NoSuchElementException异常调用poll()方法返回null

怎么确保一个集合不能被修改?

调用Collections.unmodifiablexxx()方法。

数组的特点

  • 有序性:数组中的元素是有序的,通过下标来访问。
  • 不可变性:数组一旦初始化,则长度(数组中元素的个数)不可变。 数组是一种连续存储线性结构,元素类型相同,大小相等。

Java中常见的集合

  • 顶层父接口:Map接口、Collection接口
  • Collection接口的子接口:List接口、Set接口
  • Map接口的实现类:HashMap、TreeMap、Hashtable、ConcurrentHashMap、LinkedHashMap
  • Set接口的实现类:HashSet、TreeSet、LinkedHashSet
  • List接口的实现类:ArrayList、LinkedList、Stack、Vector

简单聊聊 Set、List、Map的区别

List接口

  • 可以允许重复的对象。
  • 可以插入多个null元素。
  • 是一个有序容器,保持了每个元素的插入顺序,输出的顺序就是插入的顺序。

Set接口

  • 不允许重复对象
  • 无序容器,你无法保证每个元素的存储顺序,TreeSet通过 Comparator 或者 Comparable 维护了一个排序顺序。
  • 只允许一个 null 元素

Map接口

  • 键值对
  • 可以有多个NULL值,但只能有一个NULL键

使用场景

如果经常使用下标来访问集合的话且需要有序集合,就使用List接口。如果查询多、增删少就用ArrayList,如果查询少、增删多就用LinkedList。

如果需要保证元素的唯一性,就使用Set接口。如果不需要排序就使用HashSet、不然可以使用TreeSet、LinkedHashSet等。

如果你以键和值的形式进行数据存储那么 Map 是你正确的选择。你可以根据你的后续需要从 Hashtable、HashMap、TreeMap 中进行选择。

为什么ArrayList的elementData是用transient修饰的

首先要知道被transient修饰的变量 不参与序列化的过程

ArrayList实现了Serializable接口,这意味着ArrayList接口是可以被序列化的。但在序列化的时候elementData不一定是满的,例如elementData创建了10大小的数组但只使用3个,所以为了节省空间,没必要序列化整个数组,因此ArrayList使用transient修饰了elementData,重写了writeObject方法。

HashSet如何检测对象是否重复

当你把对象加入HashSet时,HashSet 会先计算对象的hashcode值来判断对象加入的位置,同时也会与其他加入的对象的hashcode值作比较,如果没有相符的 hashcodeHashSet 会假设对象没有重复出现。但是如果发现有相同 hashcode 值的对象,这时会调用equals()方法来检查 hashcode相等的对象是否真的相同。如果两者相同,HashSet 就不会让加入操作成功。

HashMap的底层实现

JDK1.8之前

JDK1.8 之前HashMap 底层是 数组链表 结合在一起使用也就是 链表散列HashMap 通过 keyhashCode 经过扰动函数处理过后得到 hash 值,然后通过 (n - 1) & hash判断当前元素存放的位置(这里的 n 指的是数组的长度),如果当前位置存在元素的话,就判断该元素与要存入的元素的 hash 值以及 key 是否相同,如果相同的话,直接覆盖,不相同就通过拉链法解决冲突。

所谓扰动函数指的就是 HashMaphash 方法。使用 hash 方法也就是扰动函数是为了防止一些实现比较差的 hashCode() 方法 换句话说使用扰动函数之后可以减少碰撞。

JDK1.8之后

JDK1.8大部分都与之前一样,只是在解决哈希冲突的地方有了比较大的变化。当链表长度大于阈值(默认为 8)(将链表转换成红黑树前会判断,如果当前数组的长度小于 64,那么会选择先进行数组扩容,而不是转换为红黑树)时,将链表转化为红黑树,以减少搜索时间。

ps:红黑树是一个自平衡的二叉查找树.

HashSet,TreeSet和LinkedHashSet三者的异同之处

  • 如果需要一个访问快速的Set,就用HashSet
  • 如果需要一个排序的Set,就用TreeSet
  • 如果需要记录插入时的顺序,就用LinkedHashSet

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

为了加快哈希计算以及减少哈希冲突

“取余(%)操作中如果除数是 2 的幂次则等价于与其除数减一的与(&)操作(也就是说 hash%length==hash&(length-1)的前提是 length 是 2 的 n 次方;)。” 并且 采用二进制位操作 &,相对于%能够提高运算效率,这就解释了 HashMap 的长度为什么是 2 的幂次方。

length 为偶数时,length-1 为奇数,奇数的二进制最后一位是 1,这样便保证了 hash &(length-1) 的最后一位可能为 0,也可能为 1(这取决于 h 的值),即 & 运算后的结果可能为偶数,也可能为奇数,这样便可以保证散列的均匀性