Java基础之—集合类详解

Java中集合类的关系图谱

Collection关系图:

在这里插入图片描述

Map关系图:

在这里插入图片描述

Collection vs. Collections

首先要明确的是,Collection 和 Collections是两个不同的概念。Collection是一个接口,所有的集合类(除Map外)都要继承(实现)自该接口。它提供了对集合对象进行基本操作的通用接口方法。Collections是一个包装类,它包含有各种有关集合操作的静态多态方法。(Collections是一个工具类,不能实例化)

参考:

Java集合类(四)—TreeSet
Java中集合类的关系图谱

一、 ArrayList与LinkedList源码分析

1、ArrayList

在这里插入图片描述

内部结构
/**
     * Default initial capacity.
     * ArrayList 默认的数组容量
     */
    private static final int DEFAULT_CAPACITY = 10;

    /**
     * Shared empty array instance used for empty instances.
     *  用于空实例的共享空数组实例
     */
    private static final Object[] EMPTY_ELEMENTDATA = {};

    /**
     * Shared empty array instance used for default sized empty instances. We
     * distinguish this from EMPTY_ELEMENTDATA to know how much to inflate when
     * first element is added.
     * 另一个共享空数组实例,用的不多,用于区别上面的EMPTY_ELEMENTDATA
     */
    private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {};

    /**
     * The array buffer into which the elements of the ArrayList are stored.
     * The capacity of the ArrayList is the length of this array buffer. Any
     * empty ArrayList with elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA
     * will be expanded to DEFAULT_CAPACITY when the first element is added.
     * ArrayList底层的容器  
     */
    // Android-note: Also accessed from java.util.Collections
    transient Object[] elementData; // non-private to simplify nested class access

    /**
     * The size of the ArrayList (the number of elements it contains).
     * 当前存放了多少个元素   并非数组大小
     */
    private int size;

ArrayList是基于动态数组的数据结构。实现了list接口,是以数组的方式实现的。所谓动态数组是这样实现的,如果没有指定数组的大小,则申请默认大小为10 的数组,当元素个数增加,数据无法存储时,系统会另外申请一个长度为当前长度的1.5倍的数组,然后把之前的数据拷贝(浅复制)到新建的数组中。
数组的特征是可以使用索引的方式来快速定位对象的位置。适合读取数据。

2、LinkedList

在这里插入图片描述
LinkedList 是一个继承于AbstractSequentialList的双向链表。它也可以被当作堆栈、队列或双端队列进行操作。有关索引的操作可能从链表头开始遍历到链表尾部,也可能从尾部遍历到链表头部,这取决于看索引更靠近哪一端。
LinkedList 实现 List 接口,能对它进行队列操作。
LinkedList 实现 Deque 接口,即能将LinkedList当作双端队列使用。
LinkedList 实现了Cloneable接口,即覆盖了函数clone(),能克隆。
LinkedList 实现java.io.Serializable接口,这意味着LinkedList支持序列化,能通过序列化去传输
LinkedList 是非同步的。

内部结构:
	transient int size = 0;

    /**
     * Pointer to first node. 指向链表头部
     */
    transient Node<E> first;

    /**
     * Pointer to last node.指向链表尾部
     */
    transient Node<E> last;

	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;
        }
    }
具体请参考:

ArrayList与LinkedList区别源码分析

二、Map

1、HashMap & ConcurrentHashMap
  • HashMap:实现了Map接口,数组+链表+红黑树,依据hashCode存储数据。非线程安全。
  • ConcurrentHashMap:线程安全。实现了ConcurrentMap接口,使用锁分段技术,将数据分成一段一段的存储,给每一段数据配一把锁,当一个线程占用锁访问其中一个段数据的时候,其他段的数据也能被其他线程访问。【具体细节待整理!!!】
  • 如果不涉及到多线程处理的情况,就用hashMap,因为效率比较高。在有并发请求的场景中,如果数据的强一致性比较重要,那么就请使用hashTable,因为**ConcurrentHashMap的get,clear,iterator 都是弱一致性的**。如果效率要求比较高,那么就使用ConcurrentHashMap,因为他不会像hashTable那样产生阻塞。【数据一致性问题有待学习!!!】
具体参考:

HashMap实现原理及源码分析
Hash线程不安全
Java中集合类的关系图谱

2、HashTable
HashTable的类结构:
public class Hashtable<K,V>
             extends Dictionary<K,V>
             implements Map<K,V>, Cloneable, java.io.Serializable {
 
	// Entry数组:用于存放集合中的元素
	private transient Entry<K,V>[] table;
 
	// 集合中Entry键值对的数量,并不是HashTable容器的大小
	private transient int count;
 
	// 阈值
	private int threshold;
 
	// 装载因子/加载因子
	private float loadFactor;
 
	// 记录集合的修改次数:用于实现"fail-fast"快速失败机制
	private transient int modCount = 0;
}
	

HashTable 继承了 Dictionary 类,实现了 Map 接口。其中 Dictionary 类是可将任何键映射到相应值的类(如 Hashtable)的抽象父类。每个键和每个值都是一个对象。在任何一个 Dictionary 对象中,每个键至多与一个值相关联。Map是”key-value键值对”接口。

HashTable与HashMap区别:
  1. HashTable 基于 Dictionary 类,而 HashMap 是基于AbstractMap。
  2. Hashtable中key和value都不允许为null,而HashMap中key和value都允许为null(key只能有一个为null,而value则可以有多个为null)。
  3. hashTable线程安全,HashMap非线程安全。HashTable的同步方法都被synchronized修饰,当一个线程访问同步方法时,其他访问线程可能会进入阻塞或轮询状态。效率低。
  4. HashTable在不指定容量的情况下的默认容量为11,而HashMap为16。Hashtable不要求底层数组的容量一定要为2的整数次幂,而HashMap则要求一定为2的整数次幂。
  5. Hashtable扩容时,将容量变为原来的2倍加1,而HashMap扩容时,将容量变为原来的2倍。
具体参考:

【搞定Java集合框架】第6篇:HashTable 的详解

二、 HashSet与TreeSet

1、 HashSet

HashSet是以HashMap作为底层数据结构实现的。HashMap 是作为键值对 key-value 进行存储的,而 HashSet不是键值对,那么选择 HashMap 作为实现,其原理就是存储在 HashSet 中的数据 作为 Map 的 key,而 Map 的value 统一为 一个常量字段PRESENT。对HashSet调用add、remove、contains等操作,其实都是在内部通过调用HashMap的相应操作来实现的。

具体参考:

JDK1.8源码(八)——java.util.HashSet 类

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值