学习日记-day05(java基础)

一.集合

1.集合体系图

2.集合主要有两种(单列集合和双列集合)

3.Collection接口有两个重要的子接口List和Set,他们的实现子类都是单列集合.

3.Map接口的实现子类是双列集合,存放的k-v.

4.List集合:

(1)List集合是有序的并且元素可以重复

(2)List集合中每个元素都有其索引值,即支持索引.

(4)collection集合的遍历:  collection的实现类中都有一个iterator方法,用于返回实现了iterator的对象,该对象也被成为迭代器.

(5)list接口主要方法:  (除了继承collection接口的方法,也就是list特有的一些方法)

             (1)void add(int index, Eelement):在指定位置插入元素,后面的元素都往后移一个元素

             (3)boolean addAll(int index,Collection col):在指定的位置中插入c集合全部的元素,如果集合发生改变,则返回true,否则返回false。意思就是当插入的集合c没有元素,那么就返回false,如果集合c有元素,插入成功,那么就返回true。

            (4)Object get(int index): 返回指定位置的元素.如果下标超出集合范围,会抛异常.

            (5)int indexOf(Object obj):返回 obj 在集合中首次出现的位置,这里面判断是否为该元素时是通过obj.equals()来判断的.

            (6)int lastIndexOf(Object obj):返回 obj 在当前集合中末次出现的位置,原理同上

            (7)Object remove(int index):移除指定 index 位置的元素,并返回此元素.

            (8)Object set(int index, Object ele):设置指定 index 位置的元素为 ele , 相当于是替换.

            (9)List subList(int fromIndex, int toIndex):返回从 fromIndex 到 toIndex 位置的子集合,注意返回的子集合 fromIndex <= subList < toIndex

(6) ArrayList集合的扩容机制:

             (1)第一步:创建一个ArrayList集合,如果是无参构造或者是调用有参构造但是参数为0,那么ArrayList类中的数组会初始化一个size=0的数组。也就是空数组.如果调用的有参构造但是参数大于0,则数组会初始化一个size为传入参数的数组.

               (2)  第二步:  添加元素, 首先会判断是否是第一次添加(通过判断当前数组是否为空数组), 如果是第一次添加,并且添加的元素个数小于默认容量10时,则将数组需要的大小设为10,如果添加的元素个数大于默认容量时,则将数组需要的大小设为要添加的元素个数.

              (3)  第三部:  得到数组需要的大小后, 要讲数组需要的大小与目前大小比较,如果目前数组大小不够需要的数组大小,则进行扩容,扩容为(目前大小+目前大小/2),如果扩容以后的大小仍然不够需要的大小,则直接将数组扩容到需要的大小,

(7)Vector: 和ArrayList几乎相同,只是Vector是线程安全的(加了synchronized),效率比较低.

(8)Vector扩容机制:

             (1) 第一步: 创建一个Vector集合,如果是无参构造则内部数组直接初始化一个size=10的数组,有参构造则初始化一个size为传入的参数大小的数组.

             (2)第二步: 添加元素,判断添加后的元素个数是否比当前数组的长度大,如果大,则进行扩容,默认就是扩容至原数组长度的的两倍.如果扩容后的大小还是不够添加后的元素个数,则会直接扩容至大小为添加后元素的个数.

             (3) 注意:创建Vector集合时,可以指定该数组每次扩容的增量.

(9)LinkedList:底层是一个双向链表,双向链表中增删时不用像数组一样需要移动元素,所以增删效率比较高,但是查找效率比较低.

(10)List集合的遍历方式:

          (1) 通过元素的索引遍历。

for (int i = 0; i < list.size(); i++) {
    System.out.print(list.get(i) + ",");
}

          (2) 通过迭代器遍历    注意:遍历过程中不能进行集合的修改和删除。

Iterator iterator = list.iterator();
while (iterator.hasNext()) {
    System.out.print(iterator.next() + ",");
}

         (3) 通过增强for循环   注意:其实也是使用的迭代器

for (Integer i : list) {
    System.out.print(i + ",");
}

注意: for循环是使用迭代器实现的遍历,所以里面也不能直接使用集合的移出元素的方法。

5.Set集合

(1) Set集合是无序且不能重复的,其中的重复是根据对象的equals值来比较的.

(2)Set集合的遍历:

              (1)使用迭代器

Iterator iterator = set.iterator(); 
while (iterator.hasNext()) { 
Object obj = iterator.next(); 
System.out.println("obj=" + obj);
 }

           (2)使用增强for循环

for (Object o : set) {
System.out.println("o=" + o); 
}

(3)HashSet的底层是HashMap,HashMap的底层是哈希表(数组+链表+红黑树)

(4)HashSet添加数据时的思路:

(6)我们知道HashMap的底层是和哈希表(数组+链表+红黑树),要想弄懂HashMap的原理,必须先知道哈希表这个数据结构,哈希表这个数据结构可以通过(数组+链表)实现,其主要的思想就是让不同的值放在同一个数组下标的位置,而同一个数组下标的位置用链表来存储多个不同的值,那么怎么让不同的值或者对象放在同一个数组下标呢,这就要使用一种规则,这个规则其实就是一个函数,我们称它为哈希函数,而通过这个函数我们得到的值就叫做哈希值,这个哈希值就是我们对应的下标索引。知道了哈希表数据结构的思想之后我们再来看看HashMap是如何通过哈希表这种数据结构来存储数据的。对于对象,我们是通过equals来判断对象是否相同,通过hascode来得到一个对象的哈希值,我们要想使用哈希表这种数据结构,就得保证equals对应唯一的hascode,而一个hascode对应不同的equals,所以重写equals时要重写hascode来保证这个。然后我们将元素放在了哈希表这种数据结构中后,我们可以看出,不同的对象(equals判断)可能会在一个位置,而相同的对象肯定在一个位置。但是,HashMap它要求不能放置重复的元素(equals判断的),所以我们在添加元素时,要判断当前数组下标位置的链表是否有和自己相同的元素,但是这样判断效率比较低,所以hashMap底层采用了一种方法来优化,我们之前说的将hash值当成数组下标,但是hashmap将hash值又通过一种哈希函数得到了一个hash值,将这个hash值作为数组下标,这时同一个下标位置,存放的值的hash值也可能不同了,我们就可以判断这个hash值是否相同,这个hash值如果相同,那么就再用equals判断一下,如果hash不同,那么equasl肯定不同了。

(7).HashSet的扩容机制和转换为红黑树.

(7)LinkedHashSet: 是HashSet的子类,它的底层是LinkedHashMap(是HashMap的子类)

(8) LinkedHashMap底层结构是 数组+双向链表.

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

面向工作编程的程序猿

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值