JAVA集合框架

JAVA集合框架

List、Set:
Java除了以Map结尾的类之外,其他都实现了Collection接口,并且以Map结尾的类都实现了 Map接口
List 、Set、Map的区别:
List 里面的元素有序 可重复
Set 里面的元素无序 不可重复
Map 里面存储的是键值对 key无序 不可重复 value无序 可重复

集合框架的底层结构
List:
ArrayList: Object[]数组作为底层存储结构
Vector:Object[]数组作为底层存储结构,
LinkedList:双向链表作为底层存储结构

Set:
HashSet: 无序 唯一 基于HashMap实现,底层采用hashMap保存数据
LinkedhashSet: 是HashSet的子类,内部使用LinkedhashMap实现,
TreeSet: 有序 唯一 底层:红黑树

Map:
HashMap: 由数组+链表组成的,数组是 HashMap 的主体,链表则是主要为了解决哈希冲突而存在的(“拉链法”解决冲突)DK1.8 以后在解决哈希冲突时有了较大的变化,当链表长度大于阈值(默认为 8)(将链表转换成红黑树前会判断,如果当前数组的长度小于 64,那么会选择先进行数组扩容,而不是转换为红黑树)时,将链表转化为红黑树,以减少搜索时间

LinkedHashMap:LinkedHashMap 继承自 HashMap,所以它的底层仍然是基于拉链式散列结构即由数组和链表或红黑树组成。另外,LinkedHashMap 在上面结构的基础上,增加了一条双向链表,使得上面的结构可以保持键值对的插入顺序。同时通过对链表进行相应的操作,实现了访问顺序相关逻辑。

Hashtable: 数组+链表,数组是 HashMap 的主体,链表则是主要为了解决哈希冲突 线程安全 但是性能较差

TreeMap: 红黑树

Arraylist 和 Vector 的区别

Arraylist :线程不安全
Vector :线程安全

Arraylist 与 LinkedList 区别
线程安全:都不安全
底层数据结构:数组 双向链表
插入和删除是否受元素位置的影响:
是否支持快速随机访问:支持 不支持
内存空间占用:在list列表结尾回预留一定的空间 在它的每一个元素都需要消耗比 ArrayList 更多的空间用来存储 前指针和后指针

ArrayList 的扩容机制
在添加大量元素前,应用程序可以使用ensureCapacity操作来增加 ArrayList 实例的容量。这可以减少递增式再分配的数量。

以无参数构造方法创建 ArrayList 时,实际上初始化赋值的是一个空数组。当真正对数组进行添加元素操作时,才真正分配容量。即向数组中添加第一个元素时,数组容量扩为 10。、

 /**
     * 将指定的元素追加到此列表的末尾。
     */
    public boolean add(E e) {
   //添加元素之前,先调用ensureCapacityInternal方法
        ensureCapacityInternal(size + 1);  // Increments modCount!!
        //这里看到ArrayList添加元素的实质就相当于为数组赋值
        elementData[size++] = e;
        return true;
    }
//得到最小扩容量
    private void ensureCapacityInternal(int minCapacity) {
        if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {
              // 获取默认的容量和传入参数的较大值
            minCapacity = Math.max(DEFAULT_CAPACITY, minCapacity);
        }

        ensureExplicitCapacity(minCapacity);
    }

当add第一个元素的时候,minCapacity 为1,在 Math.max()方法比较后,minCapacity 为 10。

 //判断是否需要扩容
    private void ensureExplicitCapacity(int minCapacity) {
        modCount++;

        // overflow-conscious code
        if (minCapacity - elementData.length > 0)
            //调用grow方法进行扩容,调用此方法代表已经开始扩容了
            grow(minCapacity);
    }

当add第一个元素进来的时候,elementData.length 为 0 ,因为执行了ensureCapacityInternal方法,所以 minCapacity 此时为 10,此时,minCapacity - elementData.length > 0成立,所以会进入 grow(minCapacity) 方法。

当add第二个元素进来的时候,此时的elementData.length=10,所以minCapacity - elementData.length > 0不成立,不会进入grow函数。

添加元素知道为第11个元素时,minCapacity - elementData.length > 0成立,会进入 grow(minCapacity) 方法进行扩容。

Set:
我们需要对一个集合使用自定义排序时,需要重写compareTo() (实现Comparable接口)或compare()(comparator?)方法或者使用Collections.sort()

无序性和不可重复性的含义
无序性不等于随机性 ,无序性是指存储的数据在底层数组中并非按照数组索引的顺序添加 ,而是根据数据的哈希值决定的。
不可重复性是指添加的元素按照 equals()判断时 ,返回 false,需要同时重写 equals()方法和 HashCode()方法。(所以为什么要同时重写两个函数也是需要知道的)

HashSet、LinkedHashSet 和 TreeSet 三者的异同
HashSet 是 Set 接口的主要实现类 ,HashSet 的底层是 HashMap,线程不安全的,可以存储 null 值;

LinkedHashSet 是 HashSet 的子类,能够按照添加的顺序遍历;

TreeSet 底层使用红黑树,能够按照添加元素的顺序进行遍历,排序的方式有自然排序和定制排序。

Map 接口
HashMap 和 Hashtable 的区别
线程:线程不安全 线程安全
效率:高 稍低
对 Null key 和 Null value 的支持: 支持 一个key null 多个value null 不支持
初始容量大小和每次扩充容量大小的不同 : ① 创建时如果不指定容量初始值,Hashtable 默认的初始大小为 11,之后每次扩充,容量变为原来的 2n+1。HashMap 默认的初始化大小为 16。之后每次扩充,容量变为原来的 2 倍。② 创建时如果给定了容量初始值,那么 Hashtable 会直接使用你给定的大小,而 HashMap 会将其扩充为 2 的幂次方大小
底层数据结构:数组和链表 结合在一起使用也就是 链表散列,HashMap 在解决哈希冲突时有了较大的变化,当链表长度大于阈值(默认为 8)(将链表转换成红黑树前会判断,如果当前数组的长度小于 64,那么会选择先进行数组扩容,而不是转换为红黑树)时,将链表转化为红黑树,以减少搜索时间。Hashtable 没有这样的机制。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值