Java集合看完这个再去看面试题

集合概览

  • Collection接口:单列集合,用来存储一个一个的对象
    - List接口:存储有序的、可重复的数据。->ArrayList、LinkedList、Vector
    - Set接口:存储无序的、不可重复的数据 ->HashSet、LinkedHashSet、TreeSet
  • Map接口:双列集合,用来存储一对(key - value)一对的数据->HashMap、LinkedHashMap、TreeMap、Hashtable、Properties

tips:List接口和Set接口属于Collection的子接口,Map不属于

List

List概览
  • List接口:存储有序 可重复 的数据
    - ArrayList:作为List接口的主要实现类;线程不安全 的,效率高;底层使用Object数组存储
    - LinkedList:对于频繁的插入、删除操作,使用此类效率比ArrayList高;底层使用 双向链表 存储
    - Vector:作为List接口的古老实现类;线程安全 的,效率低;底层使用Object[]数组存储
ArrayList的源码分析(掌握)
jdk1.7时的ArrayList

1.空参初始化 -> ArrayList list = new ArrayList();->这时底层初始化了一个长度为10的Object[]数组elementData
2.添加数据 -> list.add(123) -> elementData[0] = new Integer(123);
3.扩容->如果某次的添加导致底层elementData数组容量不够,则扩容->
默认情况下,扩容为原来的容量的1.5倍,同时需要将原有数组中的数据复制到新的数组中。

jdk1.8时的ArrayList的变化

1.空参初始化,底层Object[]数组初始化为{},并没有创建长度为10的数组,第一次调用add()时,底层才创建了长度10的数组,并将数据添加到elementData[0]
2.添加和扩容与jdk1.7无异

小结jdk7中的ArrayList的对象的创建类似于单例的饿汉式,而jdk8中的ArrayList的对象的创建类似于单例的懒汉式,好处为延迟了数组的创建,节省内存。

LinkedList的源码分析(了解)
ArrayList底层存储数据的是Object[]数组,而LinkedList底层存储数据的是双向链表

初始化:LinkedList list = new LinkedList(); ->内部声明了Node类型的first和last属性,默认值为null
添加:list.add(123);->将123封装到Node中,创建了Node对象。

底层Node的定义

	private static class Node<E> {
             E item;
             Node<E> next;
             Node<E> prev;

             Node(Node<E> prev, E element, Node<E> next) {
             this.item = element;
             this.next = next;
             this.prev = prev;
             }
        }
Vector的源码分析(了解)

jdk7和jdk8中通过*Vector()*构造器创建对象时,底层都创建了长度为10的数组。

  •  在扩容方面,默认扩容为原来的数组长度的2倍。    
    

Set

Set概览
  • Set接口:存储无序 不可重复 的数据
    - HashSet:作为Set接口的主要实现类;线程不安全的;可以存储null值
    - LinkedHashSet:作为HashSet的子类;遍历其内部数据时,可以按照添加的顺序遍历,对于频繁的遍历操作,LinkedHashSet效率高于HashSet.
    - TreeSet:可以按照添加对象的指定属性,进行排序
HashSet的源码分析(掌握)
HashSet的底层结构图

添加元素的过程:
1.我们向HashSet中添加元素a,首先调用元素a所在类的 hashCode() 方法,计算元素a的哈希值
2.此哈希值接着通过某种算法计算出在HashSet底层数组中的存放位置(即为索引位置)
3.判断数组此位置上是否已经有元素:
情况①:如果此位置上没有其他元素,则元素a添加成功。
情况②:如果此位置上有其他元素b(或以链表形式存在的多个元素),则比较元素a与元素b的hash值,如果hash值不相同,则元素a添加成功。
情况③:如果hash值相同,进而需要调用元素a所在类的equals()方法: equals()返回true,元素a添加失败,equals()返回false,则元素a添加成功

  • HashSet的底层结构图(数组加链表)
    在这里插入图片描述

tips: 其实这个图也是HashMap的底层结构图,为什么他们两个底层结构一样呢?因为其实HashSet底层就是一个HashMap,通过下图的代码也可以看到
在这里插入图片描述
创建了一个HashSet其实就是底层创建了一个HashMap,想了解HashMap可往后看HashMap的源码分析

HashSet jdk1.7与1.8的不同

经过比较可以添加元素时,如果添加位置上已经有了元素存在的话:
jdk1.7的处理->需要添加元素放到数组中,指向原来的元素(可理解为头插法)
jdk 8的处理->原来的元素在数组中,指向需要添加元素(可理解为尾插法)

总结七上八下

Map

写博客也太费时了把。。先休息一会儿。。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值