Java集合知识汇总

Java 集合

本文是在看过一些视频以及文章总结出的一些个人理解
Java集合常见面试题总结(上) | JavaGuide(Java面试+学习指南)

Collection 接口 (父接口)

img

# List
  • ArrayListObject[] 数组
  • VectorObject[] 数组
  • LinkedList: 双向链表(JDK1.6 之前为循环链表,JDK1.7 取消了循环)
# Set
  • HashSet(无序,唯一): 基于 HashMap 实现的,底层采用 HashMap 来保存元素
  • LinkedHashSet: LinkedHashSetHashSet 的子类,并且其内部是通过 LinkedHashMap 来实现的。有点类似于我们之前说的 LinkedHashMap 其内部是基于 HashMap 实现一样,不过还是有一点点区别的
  • TreeSet(有序,唯一): 红黑树(自平衡的排序二叉树)
# Queue
  • PriorityQueue: Object[] 数组来实现二叉堆
  • ArrayQueue: Object[] 数组 + 双指针

再来看看 Map 接口下面的集合。

# Map
  • HashMap: JDK1.8 之前 HashMap 由数组+链表组成的,数组是 HashMap 的主体,链表则是主要为了解决哈希冲突而存在的(“拉链法”解决冲突)。JDK1.8 以后在解决哈希冲突时有了较大的变化,当链表长度大于阈值(默认为 8)(将链表转换成红黑树前会判断,如果当前数组的长度小于 64,那么会选择先进行数组扩容,而不是转换为红黑树)时,将链表转化为红黑树,以减少搜索时间
  • LinkedHashMapLinkedHashMap 继承自 HashMap,所以它的底层仍然是基于拉链式散列结构即由数组和链表或红黑树组成。另外,LinkedHashMap 在上面结构的基础上,增加了一条双向链表,使得上面的结构可以保持键值对的插入顺序。同时通过对链表进行相应的操作,实现了访问顺序相关逻辑。详细可以查看:《LinkedHashMap 源码详细分析(JDK1.8)》open in new window
  • Hashtable: 数组+链表组成的,数组是 Hashtable 的主体,链表则是主要为了解决哈希冲突而存在的
  • TreeMap: 红黑树(自平衡的排序二叉树)
Iterator 迭代器

所有实现了Iteratable接口的类都可以通过iterator()方法获取迭代器

注意:重新获取iterator即可重置迭代器;

增强 for 循环
  1. 可以对 数组 和 集合 使用;
  2. 底层使用的仍然是 iterator
  3. 大写 I 可以快速生成代码(Idea)。

List 接口 可重复-有顺序

ArrayList
  1. 线程不安全

  2. ArrayList 维护了一个 Object 类型的数组 elementData – transient Object[] elementData // transient 表示该属性不会被序列化

  3. 两种构造方式(构造时数组已经初始化):

    1. 无参构造: ArrayList,则初始化 elementData 容量为0第一次添加时,则扩容至默认容量10,如需再次扩容,则扩容为当前的1.5倍(1+1/2);Vector(无参情况下) 扩容倍数是2,线程安全是因为每个方法头上添加了 synchronized
    2. 指定initialCapacity大小的构造器:初始 elementData 容量为指定大小,如需扩容,则直接扩容 elementData 为当前的1.5倍
  4. 每次添加元素时,都会触发一次扩容检查,容量不满足 size+1 就扩容

  5. 源码解读如下

    image-20220328102410246
image-20220328102321216
Vector
  1. 线程安全
  2. 如果无参,默认10,满后,2倍扩容;如果指定大小,满后则每次直接2倍扩容(优先使用自定义增量capacityIncrement)
  3. 有参构造可以指定扩容大小 Vector(int initialCapacity, int capacityIncrement)
  4. 源码解读如下
====================================================
public synchronized boolean add(E e) {
   
    modCount++;
    ensureCapacityHelper(elementCount + 1);   // 扩容检查
    elementData[elementCount++] = e;
    return true;
}
====================================================
private void ensureCapacityHelper(int minCapacity) {
   
    // overflow-conscious code
    if (minCapacity - elementData.length > 0)
        grow(minCapacity);    // 真正扩容方法
}
====================================================
private void grow(int minCapacity) {
   
    // overflow-conscious code
    int oldCapacity = elementData.length;
    //扩容的关键算法
    int newCapacity = oldCapacity + ((capacityIncrement > 0) ?
                                     capacityIncrement : oldCapacity);
    if (newCapacity - minCapacity < 0)    // 扩容后仍不满足最小capacity要求
        newCapacity = minCapacity;
    if (newCapacity - MAX_ARRAY_SIZE > 0)    // 超过最大容量
        newCapacity = hugeCapacity(minCapacity);
    elementData = Arrays.copyOf(elementData, newCapacity);
}
====================================================
LinkedList

结构

  1. 底层维护了一个双向链表
  2. 可以添加任意元素
  3. 其中有两个属性firstlast分别指向首节点和尾结点
  4. 每个节点(Node对象),里面又维护了prevnextitem三个属性,其中通过prev指向前一个,通过next指向后一个节点,最终实现双向链表
  5. LinkedList 增删快,查找慢
  6. 源码解读如下(尾插头删)
-----------------------------
public boolean add(E e) {
   
        linkLast(e);
        return true;
    }
-----------------------------
void linkLast(E e) {
   
        final Node<E> l = last;  // 旧尾结点
        final Node<E> newNode = new Node<>(l, e, null);  // 创建新节点
        last = newNode;     // 新节点上位尾结点
        if (l == null)
            first = newNode; // 第一个节点 first->a  last->a
        else
            l.next = newNode;  // 新节点是从尾部连接的!新节点赋值->旧尾结点.next 
        size++;
        modCount++;
    }
-----------------------------
public E remove() {
   
        return removeFirst();  //注意是第一个
    }
public E removeFirst() {
   
        final Node<E> f = first;
        if (f == null)
            throw new NoSuchElementException();
        return unlinkFirst(f);
    }
-----------------------------
private E unlinkFirst(Node<E> f) {
   
        // assert f == first && f != null;
        final E element = f.item;
        final Node
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值