Java集合详解

1,集合可以分为两大类,Collection和Map

1,collectin下面又有两个子接口

在这里插入图片描述

2,list接口下面有三个常用的实现类

在这里插入图片描述

3、set接口下有三个常用的实现类

在这里插入图片描述

4、map接口下有常用的五个实现类

在这里插入图片描述

详细介绍

在这里插入图片描述

2、List接口详解

1、list接口

存储有序的,可重复的数据,常用的实现子类有三种,ArrayList、LinkedList、Vector

2、list三个子类的不同点

ArrrayList:作为list接口的主要实现类;是线程不安全的,效率高,底层使用Object[] elementData存储
LinkedList:对于频繁的插入,删除操作,使用此效率比ArrayList高;底层使用的是双向链表
Vector:作为List接口的古老实现类,是线程安全的,效率低,底层使用的是Object[] elementData存储

3,ArrayList的底层源码分析(基于jdk1.8)

(1)当我们去创建一个ArrayList的时候底层会先为我们创建一个空数组,也就是elementData[]={}

//ArrayList的空参构造器
	private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {};
 public ArrayList() {
        this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA;
    }

(2)当我们第一次添加数据的时候,ArrayList会为我们创建一个容量为10的数组

public boolean add(E e) {
		//检查容器的容量是否足够,如果不足够就会扩容
        ensureCapacityInternal(size + 1);  // Increments modCount!!
        elementData[size++] = e;
        return true;
    }
private static final int DEFAULT_CAPACITY = 10;
private void ensureCapacityInternal(int minCapacity) {
        //第一次添加的时候会执行if语句里面的内容,DEFAULT_CAPACITY =10
        if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {
            minCapacity = Math.max(DEFAULT_CAPACITY, minCapacity);
        }

        ensureExplicitCapacity(minCapacity);
    }
  private void ensureExplicitCapacity(int minCapacity) {
        modCount++;

        // 如果所需的容器容量不够就会进行扩容
        if (minCapacity - elementData.length > 0)
            grow(minCapacity);
    }
    //扩容的方法,如果容量不够就会扩容到原来的1.5倍
 private void grow(int minCapacity) {
        // overflow-conscious code
        int oldCapacity = elementData.length;
        //扩容后的容量,是原来的1.5倍,前提是不是第一次添加数据的时候,因为第一次添加数据的时候,oldCapacity=0,扩容后还是0;
        int newCapacity = oldCapacity + (oldCapacity >> 1);
        if (newCapacity - minCapacity < 0)
            newCapacity = minCapacity;
        if (newCapacity - MAX_ARRAY_SIZE > 0)
            newCapacity = hugeCapacity(minCapacity);
        // minCapacity is usually close to size, so this is a win:
        elementData = Arrays.copyOf(elementData, newCapacity);
    }

(3)当我们添加多个数据的时候,如果当前容量不够,就会扩容,扩容到原来的1.5倍,扩容的过程和步骤2一样。
(4)总结
当我们创建一个ArrayList的时候,底层回我们创建一个容量为0的数组
当我们第一次添加的时候,ArrayLIst会为我们创建一个容量为10的数组
但我们添加的数据大于,当前数组容量的时候会进行扩容,扩容为原来的1.5倍,同时将原来数组的内容复制到新的数组中

4、LinkedList的底层源码分析

LikendList底层是双向链表,其实就是对双向链表的操作

5、Vector源码分析

vector现在基本不用了,所以在这里简单总结一下
(1)Vector的底层也是数组,在一开始创建的时候,会创建一个容器为10的数组
(2)当我们添加数据的时候容器不够的时候,会进行扩容,扩容到原来的2倍

3、Set接口详解

1、set接口常用的实现类

HashSet, LinkedHashSet ,TreeSet

2、HashSet

HashSet:作为set接口的主要实现类,是线程不安全的,可以存储null值,底层是HashMap

3、linkedHashSet

LinkedHashSet:作为HashSet的子类,遍历其内部数据的时候,可以按照添加的数据

4、TreeSet

TreeSet:可以按照添加对象的属性进行排序,底层是TreeMap

4、Map接口

1、map常用的子类

在这里插入图片描述

2、HashMap源码分析
 *  三、HashMap的底层实现原理?以jdk7为例说明:
 *      HashMap map = new HashMap():
 *      在实例化以后,底层创建了长度是16的一维数组Entry[] table。
 *      ...可能已经执行过多次put...
 *      map.put(key1,value1):
 *      首先,调用key1所在类的hashCode()计算key1哈希值,此哈希值经过某种算法计算以后,得到在Entry数组中的存放位置。
 *      如果此位置上的数据为空,此时的key1-value1添加成功。 ----情况1
 *      如果此位置上的数据不为空,(意味着此位置上存在一个或多个数据(以链表形式存在)),比较key1和已经存在的一个或多个数据
 *      的哈希值:
 *              如果key1的哈希值与已经存在的数据的哈希值都不相同,此时key1-value1添加成功。----情况2
 *              如果key1的哈希值和已经存在的某一个数据(key2-value2)的哈希值相同,继续比较:调用key1所在类的equals(key2)方法,比较:
 *                      如果equals()返回false:此时key1-value1添加成功。----情况3
 *                      如果equals()返回true:使用value1替换value2。
 *
 *       补充:关于情况2和情况3:此时key1-value1和原来的数据以链表的方式存储。
 *
 *      在不断的添加过程中,会涉及到扩容问题,当超出临界值(且要存放的位置非空)时,扩容。默认的扩容方式:扩容为原来容量的2倍,并将原有的数据复制过来。
 *
 *      jdk8 相较于jdk7在底层实现方面的不同:
 *      1. new HashMap():底层没有创建一个长度为16的数组
 *      2. jdk 8底层的数组是:Node[],而非Entry[]
 *      3. 首次调用put()方法时,底层创建长度为16的数组
 *      4. jdk7底层结构只有:数组+链表。jdk8中底层结构:数组+链表+红黑树。
 *         4.1 形成链表时,七上八下(jdk7:新的元素指向旧的元素。jdk8:旧的元素指向新的元素)
           4.2 当数组的某一个索引位置上的元素以链表形式存在的数据个数 > 8 且当前数组的长度 > 64时,此时此索引位置上的所数据改为使用红黑树存储。
 *
 *      DEFAULT_INITIAL_CAPACITY : HashMap的默认容量,16
 *      DEFAULT_LOAD_FACTOR:HashMap的默认加载因子:0.75
 *      threshold:扩容的临界值,=容量*填充因子:16 * 0.75 => 12
 *      TREEIFY_THRESHOLD:Bucket中链表长度大于该默认值,转化为红黑树:8
 *      MIN_TREEIFY_CAPACITY:桶中的Node被树化时最小的hash表容量:64
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
// 谢谢回答邀请。这是我关于《Java集合详解》的简要回答。 Java集合Java编程语言提供的一种数据容器,用于存储、操作和访问数据。Java集合框架包含了各种不同类型的集合类,如列表、集合和映射等,以满足不同的数据存储和操作需求。 Java集合框架的核心接口是Collection接口和Map接口。Collection接口是用于存储元素的容器,其中包含了常用的集合操作方法,如添加、删除、查找和遍历等。常见的Collection实现类有ArrayList、LinkedList和HashSet等。Map接口是一种键值对的映射容器,其中每个元素包含一个键和对应的值。常见的Map实现类有HashMap、TreeMap和LinkedHashMap等。 在Java集合框架中,还有一些特殊的集合类,如队列、堆栈和优先队列等。队列是以先入先出(FIFO)的方式存储元素的容器,常用的队列类有LinkedList和ArrayDeque等。堆栈是以后入先出(LIFO)的方式存储元素的容器,常用的堆栈类有Stack和ArrayDeque等。优先队列是一种按照元素优先级进行排序的容器,常用的优先队列类有PriorityQueue等。 Java集合框架提供了丰富的功能和灵活的操作方式,可以满足不同场景下的数据存储和处理需求。使用Java集合框架可以提高代码的重用性和可维护性,减少开发和维护的工作量。同时,由于Java集合框架是开源的,广泛应用于各种Java项目中,因此具有丰富的资源和工具支持,便于开发人员快速上手和解决问题。 总之,Java集合框架是Java编程中非常重要和常用的部分,掌握好Java集合的基本概念和使用方法,对于提高代码质量和开发效率都有很大的帮助。希望这个回答对您有所帮助。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值