一起来学习吧,加油!!!
文章目录
前言
本节来学习集合
一、了解集合
集合 : *****
学好集合 : 多练习 先学会应用,在去理解
变量 : 存储单个数据
数组 : 存储多个数据
集合 : 存储多个数据
集合与数组的区别
数组的特点 :
1.引用数据类型,数据为对象数据
2.数组长度固定,一旦确定不可改变
3.存储多个数据的类型要求相同
4.有序的,索引
集合特点 :
1.引用数据类型
2.存储任意类型的数据
3.长度跟随数据的增删进行动态改变
4.只能存储引用数据类型的数据
二、Collection
1.遍历 :
Collection接口下的所有集合类型的公共的遍历方式:
1.增强for循环|for..each
2.iterator迭代器
1)获取遍历指定集合的迭代器对象
2)重复判断是否存在下一个数据
3)重复获取下一个数据
2.泛型 :
jdk1.5新特性
参数化类型 : 数据类型作为参数传递
语法 : <参数类型>
位置 :
泛型类 : 定义类的时候允许使用泛型,在使用类的时候,可以通过泛型的使用方式传递数据类型,类中可以使用泛型
泛型方法 : 方法上使用泛型
作用 :
1.使用简单,避免类型转换异常的出现
2.增强程序的稳定性与可读性
3.便于后期维护
注意 :
方法的参数 : 方法执行中是否存在未知的,不确定的,有可能会改变的数据,如果存在定义在方法 参数的参数列表上
三、List
Set 接口 : 无序的,不可重复|唯一的
List 接口 : 有序的,可重复
有序集合(也称为序列 )。 该接口的用户可以精确控制列表中每个元素的插入位置。 用户可以通过整数索引(列表中的位置)访问元素,并搜索列表中的元素。
接口中的功能–> List下所有实现类都具有
新增功能 : 新增了一系列与索引相关的操作方法
遍历方式 --> List下所有实现类都具有
注意 :
jdk1.8之前接口中只能定义抽象方法与公共的静态的常量
jdk1.8及之后可以定义带有方法体的方法 : 默认方法->实现类对象调用 静态方法-> 通过接口名调用
与索引相关的操作使用,首先要先判断是否是否越界
1.listInterator 列表迭代器
for…each与interator在循环时进行添加操作会发生并发修改异常:
java.util.ConcurrentModificationException
当不允许这样的修改时,检测到对象的并发修改的方法可能抛出此异常。 例如,一个线程通常不允许修改Collection,而另一个线程正在迭代它。
此时我们可以使用列表迭代器:listInterator
listInterator.add(String s)会在判断条件之后添加String s,而不是在最后。
2.ArrayList
ArrayList :
存储的每个元素由单个值组成,有序的,可重复,可以根据索引进行操作的
并允许所有元素,包括null 。
底层结构 :
数组 Object[] elementData;
特点 :
根据索引查询效率高
做增删涉及到新数组的创建,原数组数据的拷贝,效率低
应用场景:
大量错查询,少量做增删的时候适合使用ArrayList
新增功能 :
void forEach(Consumer<? super E> action) 对 Iterable每个元素执行给定操作,直到处理 Iterable所有元素或操作引发异常。
遍历方式 :
for
foreach
iterator
listIterator
注意 :
如果底层存储数据的结构如果涉及到数组,关注初始容量与扩容机制,因为大部分情况,会通过空间换时间的方式提高效率
初始容量 : 10 private static final int DEFAULT_CAPACITY = 10;
扩容机制 : 在add方法的内部,通过Arrays.copyOf方法实现新数组的创建+数据的拷贝,每次扩容原容量的1.5倍 int newCapacity = oldCapacity + (oldCapacity >> 1);
3.Vector
Vector : 向量 --> 了解
Vector 与 ArrayList之间的区别:
共性 : 都是List接口下的实现类,都有序可重复的
底层结构都是数组
区别 :
1.线程安全问题|同步问题
Vector是同步的。
ArrayList线程不安全的,不同步的。
如果不需要线程安全实现,建议使用ArrayList代替Vector 。
2.扩容机制
ArrayList与Vector初始容量默认都是10
ArrayList扩容 : 1.5倍,更有利于节省内存
Vector扩容 : 2倍
4.LinkedList
LinkedList :
有序,可重复
双链表,实现所有可选列表操作,并允许所有元素(包括null )。
底层结构 : 双向链表
特点 : 查询效率低,增删效率高
应用场景 : 适合用于大量做增删,少量做查询的情况
新增功能 : 新增了一些根据链表头尾操作的功能,了解即可
遍历方式 : 与List接口相同 四种遍历方式
注意 : 请注意,此实现不同步。
四、Set
List : 有序的,可重复的
Set : 无序的,不可重复|去重的
Set :
不包含重复元素的集合。 更正式地说,集合不包含元素对e1和e2 ,使得e1.equals(e2)和最多一个null元素。
新增功能 :
static <E> Set<E> of(E... elements) 返回包含任意数量元素的不可修改集。
遍历方式 :
for..each
iterator 迭代器
注意 :
无序 : 添加的数据与内部真实存储的顺序不一致
1.TreeSet
TreeSet :
底层是由TreeMap维护
底层结构: 红黑树(平衡二叉树)
特点: 自动做升序排序
引用场景 : 实现去重,自动做升序排序的时候推荐使用
新增功能 : 新增了一些与比较相关的功能
遍历方式 :
for…each
iterator
注意 :
无序 : 存放的顺序与内部真实存储的顺序不保证一致是set的无序
Compare
想要对对象数据做比较时,需要涉及到比较器的使用
通过比较器定义比较规则,通过指定的比较规则对数据进行比较大小|是否相等,进一步可以做排序
内部比较器|自然排序|默认排序 :
比较哪一种类型的数据,比较规则定义在类型的内部,默认比较方式
类型实现Comparable接口,重写compareTo(T o)方法,方法内部定义比较规则
当内部比较器规则时候,认为不够灵活,不便于后期维护,这时候可以使用外部比较规则代替
外部比较器|定制排序|自定义排序 :
比较规则定义在类型的外部
定义一个实现类实现Comparator<T>接口,重写int compare(T o1, T o2) 方法,内部定义比较规则
注意 :
当前的实现类不是实体类,为外部的咱们用来实现接口,重写方法,为了在方法内部定义比较规则
注意 :
TreeSet集合存储数据时候,去重与排序都只看比较规则,不会调用equals去重
存储的数据必须定义比较规则|外部或者内部
2.HashSet
HashSet :
无序,去重
底层是由HashMap维护的
底层结构 : 哈希表(jdk8及之后->数组+链表+红黑树 jdk1.7及之前:数组+链表)
特点: 增删查询效率较高,但是无序,去重
应用场景 : 适用于去重下,查询增删效率都较高情况下
新增功能 : 无新增功能
遍历方式 :
for .. each
iterator迭代器
五、Map
Map : *****
多个键值对的集合,多个映射关系的集合
键值对|映射
Key -> Value
一个key只能对应一个value
map中key是唯一的,无序的 --> Set集合
map中value无序的,可重复的 --> Collection集合
1.Each
Map的遍历方式 :
1.Collection values() 获取所有的value值
2.Set keySet() 返回所有键值对的key
3.Set<Map.Entry<K,V>> entrySet() 返回此映射中包含的映射的Set视图。
2.TreeMap
TreeMap :
底层 : 红黑树
存储键值对的数据,会根据key做比较,做排序,做去重,与value无关
TreeSet底层是由TreeMap维护的
特点 : 可以根据key自动做升序排序,根据key做去重
引用场景 : 存储键值对数据时候,想根据key的值,做符合某种规则的升序|降序排序时候推荐使用
注意:
TreeMap存储过程中,排序,去重都是根据比较器决定
TreeMap是不同步的|线程不安全的
3.HashMap
HashMap : *****
基于哈希表的Map接口的实现。 此实现提供了所有可选的映射操作,并允许null值和null键。
HashSet底层就是通过HashMap维护
底层结构 : 哈希表(数组+链表+红黑树)
哈希表 : 数组(节点数组+单向链表)
初始容量 : 16
加载因子 : 0.75 ->一般不要修改
扩容阀值(扩容临界值) : 存储的数据个数>数组的长度*加载因子 就@会扩容
扩容机制 : 原容量的2倍
去重 : 是根据每一个键值对的key做去重,把所有键值对的key拿出来就是HashSet
4.HashMap与Hashtable之间区别
共同点
都是Map接口的实现类,底层结构都是哈希表
异同点 :
1.继承体系不同
2.线程是否同步|安全问题
HashMap : 线程不安全|不同步
hashtable : 线程安全|同步
3.键值对数据对null值的要求不同
HashMap : null值可以作为key与value
hashtable : null值不可以作为key与value
4.扩机机制不同
HashMap : 每次扩容原容量的2倍
newCap = oldCap << 1
hashtable : 每次扩容原容量的2倍+1
int newCapacity = (oldCapacity << 1) + 1;
5.计算hash值与位桶索引index的算法不同
HashMap :
int hash = (key == null) ? 0 : (h = key.hashCode()) ^ (h >>> 16);
int index = (n - 1) & hash
hashtable :
int hash = key.hashCode();
int index = (hash & 0x7FFFFFFF) % tab.length;
六、Properties
Properties类表示一组持久的属性。
Properties可以保存到流中或从流中加载。 属性列表中的每个键及其对应的值都是一个字符串。
引用场景 : 从配置文件中加键值对数据到java程序中
步骤 :
1.定义一个文件 .properties后缀名的文件
src下新建file->xx.properties ->文件中定义键值对的数据
2.java中构建一个Properties对象
3.让Properties加载流|从流中加载数据
4.根据key获取value
总结
以上是集合的主要内容及知识点,以后会持续进行更新