集合

目录

一.Collection接口与uilt包

Collection接口那些方法:(即List与Set实现的接口)

List集合 java.util.List

ArrayList

二.ArrayList与LinkedList

LinkedList

三.TreeSet(排序 )

四.HashMap

Map的特征

HashMap 常用的类

HashMap的原理 面试常面

HashMap的put()方法添加元素的原理:


一.Collection接口与uilt包

有关java.util包:

集合有两大父接口:

1) Collection接口: 存储一个一个元素

两大子接口:

1. List: 特征: 元素可重复,有序(拿出元素的顺序与添加顺序一致)

常用实现类: ArrayList,LinkedList

2.Set: 特征: 元素唯一,无序

常用实现类: HashSet, TreeSet

Collection接口那些方法:(即List与Set实现的接口)

1、 int size(); 返回此collection中的元素数。

2、 boolean isEmpty(); 判断此collection中是否包含元素。

3、 boolean contains(Object obj); 判断此collection是否包含指定的元素。

4、 boolean contains(Collection c); 判断此collection是否包含指定collection中的所有元素。

5、 boolean add(Object element); 向此collection中添加元素。

6、 boolean addAll(Collection c);将指定collection中的所有元素添加到此collection中

7、 boolean remove(Object element); 从此collection中移除指定的元素。

8、 boolean removeAll(Collection c); 移除此collection中那些也包含在指定collection中的所有元素。

9、 void clear(); 移除些collection中所有的元素。

10、boolean retainAll(Collectionc); 仅保留此collection中那些也包含在指定collection的元素。

11、Iterator iterator(); 返回在此collection的元素上进行迭代的迭代器。

12、Object[]toArray();把此collection转成数组。

List集合 java.util.List

List 特征: 可重复,有序(有下标 )

特有的方法:

add(int index, 元素) 在指定下标位置插入元素

Object get(int index) 获取指定位置的元素

int indexOf(元素) 找到这个元素第一次出现的位置

int lastIndexOf(元素) 找到这个元素最后一次出现的位置

remove(int index ) 删除指定位置上的元素

set(int index, 新的元素) 修改指定位置上的元素

List<E> subList(int fromIndex, int toIndex) 截取指定位置上元素, 不包括结束位置

常用的实现类: ArrayList, LinkedList

ArrayList

底层使用数组实现, 数据结构与数组一样

构造方法:

注意:

集合: 存放的元素都是对象, 如果是基本数据类型, 自动的装箱,变成包装类对象

private static final Object[]   ArrayList 底层是Object[] 数组

2) Map接口: 存储的一对一对的key-value键值对

常用实现类: HashMap,TreeMap

Arrays: 数组的帮助类Collections: Collection集合的帮助类 这个两个类的方法都是static的

二.ArrayList与LinkedList

底层使用数组,

自动扩容:

elementData[] = new int[10];

添加了10个元素, 添加11个, 新创建一个数组: 长度 = 旧数组长度 * 1.5 = 10*1.5 = 15, 再把旧数组中的元素拷贝到新数组, elementData 指向新数组

ArraylIst: 特征: 查找元素效率高, 插入,删除元素效率低

添加元素: 判断数组时候是否需要扩容 elementData的长度 < 最小容量(原来元素个数 + 1) 调用: grow(最小容量) 自动扩容

ArrayList 对elementData数组进行new操作, 初始化, 不是在new ArrayList() , 而是在第一次调用add() 方法

elementData[]={}

第一次添加元素: 初始化elementData = new Object[10];

这个集合已经有元素: 新数组长度 = 旧的数组长度 *1.5 进行数组的拷贝, Arrays.copyof() 往elementData添加新元素 elementData[size++] = 新元素;

LinkedList

LinkedList: 底层存储元素: 使用双向链表: 不连续的空间, 由n个节点组成, 节点就是一个对象: Node

LinkedList: 特征: 查询效率低, 插入,删除效率高

三.TreeSet(排序 )

Set: HashSet, 作用: 去重

判断元素是否存在, 调用 hashCode() --> equlas()

HaseSet: 底层是哈希表, HashMap, 数组加链表

TreeSet: 底层使用红黑树, 左 < 根 < 右 有序的

算法,数据结构可视化网站: 二叉搜索树,AVL树 - VisuAlgo

 红黑树的研究, 到达平衡: 变色,左旋,右旋

TreeSet: 可排序

创建TreeSet

TreeSet排序原理

1) 要求元素的类实现比较器: Comparable

compareTo方法的实现规则:

返回 0,表示 this == obj。//则不会添加新对象

返回正数,表示 this> obj //添加到原来对象的右边

返回负数,表示 this < obj // 添加到原来对的左边

使用Comparable 这种方式: 排序方式 已经写死, 动态比较无法实现: 有时需要安装年龄, 有时需要是学号,... 扩展性不好

2) 获取指定Comparator比较器 创建TreeSet时, 才指定排序方式, new TreeSet(Comparator对象), 比Comparable 扩展性好

返回 0,表示 this == obj。//则不会添加新对象

返回正数,表示 this> obj //添加到原来对象的右边

返回负数,表示 this < obj // 添加到原来对的左边

如果元素的类没有实现Comparable接口, 或者new TreeSet 指定Comparator, 往TreeSet添加元素,抛异常:

四.HashMap

Map存储的元素: 一对元素(key-value) kv键值对

Map 位于java.util包下, 接口, 常用子类: HashMap (线程不安全), HashTable(线程安全),Properties(后期使用, 配置文件)

集合只能存储对象, 1 -->Integer

Map的特征

特征: key: 唯一, value可以重复

添加元素: 新元素的key在Map集合中存在, map替换value , 如果key不存在, 添加

1.1 通过键-值(key-value)对的形式来存储数据

1.2 Map的实现:HashMap(使用频率最高的),TreeMap,HashTable

1.3 Map中,key可以为任意类型,但这里建议使用String,value也可以是任意类型

1.4 Map里面多个value可以是不同类型, 向上转型: Object

1.5 Map里面key是可以重复的,当key重复时,后存入的数据会覆盖前面的数据

1.6 Map里面,value可以重复.

1.7 Map里面的key可以为null,但是只能有一个,多个的时候,后面的会覆盖前面的

1.8 Map中value可以是null,多个value可以同时为null。

1.9 Map中的key在底层可以理解为是一个Set

HashMap 常用的类

作用: 存储的key-value对

创建:

构造方法:

常用方法: 增删改查

put(key,value) 实现添加元素与修改元素

即:修改value新元素的key在Map集合中存在, map替换value , 如果key不存在, 添加

 

value remove(key) 根据key删除key-value 对

clear() 清空map

value get(key) 根据key获取value

HashMap的原理 面试常面

存储数据结构: 哈希表--> hash算法

public  int hash(long obj){
    // 有限范围的整数        快速的存储是否包含这个数字
}

HashMap底层存储数据的结构: 数组 + 链表: 在jdk1.7之前, 在JDK1.8 数组 + 链表 /红黑树

LinkedList: 查询效率低

在JDK1.8如果当某一列的链表长度很长, 为了提高查询效率, 把链表转换为红黑树

(具体的长度为8)

链表查询时间复杂度: O(n) 红黑树时间复杂度: O(n) = log2N

HashMap的put()方法添加元素的原理:

  1. 对key进行hash算法,得到hash值

  2. 调用putVal() , 判断是否是第一次添加,如果是第一次添加, 调用resize() 对数组进行初始化

  3. 根据hash值找到元素存在table数组的那个位置(下标), 判断该位置是否为null,

3.1 如果为null, 直接创建一个Node对象, 添加到数组该位置

3.2 如果不为null: 但是该位置第一个节点的key与新添加的key一样, 直接覆盖value

3.3 如果key 不一样: 循环遍历该链表, 如果某个节点的key一样, 覆盖该节点的value

3.4 如果链表中所有的key与添加的key 都不一样, 创建一个新的Node, 添加到链表的末尾: 尾插入, jdk1.7 头插入

  1. 如果链表的长度 = 8, 并且 map的容量 > 64 , 变红黑树, 如果map容量 <= 64 , 扩容

    1. 如果map的元素个数 > 扩容阈值, 进行扩容

查看value get(key)方法的源码

存储原理:

  1. 它的底层会调用K的hashCode()方法得出hash值。

  2. 通过哈希表函数/哈希算法,将hash值转换成数组的下标.

  3. 下标位置上如果没有任何元素,就新创建一个Node节点,并添加到这个位置上。如果说下标对应的位置上有链表。此时,就会拿着k和链表上每个节点的k进行equal。如果所有的equals方法返回都是false,那么这个新的节点将被添加到链表的末尾。如其中有一个equals返回了true,那么这个节点的value将会被覆盖。

读取原理:

第一步:先调用k的hashCode()方法得出哈希值,并通过哈希算法转换成数组的下标。

第二步:通过上一步哈希算法转换成数组的下标之后,在通过数组下标快速定位到某个位置上。重点理解如果这个位置上什么都没有,则返回null。如果这个位置上有单向链表,那么它就会拿着参数K和单向链表上的每一个节点的K进行equals,如果所有equals方法都返回false,则get方法返回null。如果其中一个节点的K和参数K进行equals返回true,那么此时该节点的value就是我们要找的value了,get方法最终返回这个要找的value

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

Kblzxj

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

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

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

打赏作者

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

抵扣说明:

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

余额充值