学习目标:
1.List
学习内容:
一、List
1.概念:是一种有序,有索引,可重复的容器
2.优点:规范数据的稳定性和可读性
3.方法:
add 添加 | get检查 | indexOf/lastIndexOf 元素第一次和最后一次出现的索引
List<E> 变量名=List.of(); 返回任意不可修改的元素列表
remove 移除 | set 替换 | List<E> subList() 截取
public class Class01_List {
public static void main(String[] args) {
//泛型 <类型> : 检查集合中所有元素的数据类型
//优点: 规范数据的稳定性与可读性
List<String> list=new ArrayList();
//void add(int index, E element) 将指定元素插入此列表中的指定位置(可选操作)。
list.add("A");
list.add("cc");
list.add("fs");
//E get(int index) 返回此列表中指定位置的元素。
System.out.println(list.get(0));
list.add("cc");
//int indexOf(Object o) 返回此列表中第一次出现的指定元素的索引,如果此列表不包含该元素,则返回-1。
//int lastIndexOf(Object o) 返回此列表中指定元素最后一次出现的索引,如果此列表不包含该元素,则返回-1。
System.out.println(list.indexOf("cc"));
System.out.println(list.lastIndexOf("cc"));
//static <E> List<E> of(E... elements) 返回包含任意数量元素的不可修改列表。
List<Integer> list1=List.of(1,5,6,8,3);
System.out.println(list1);
// list1.add(2);
// System.out.println(list1);
//E remove(int index) 删除此列表中指定位置的元素(可选操作)。
//只会移出第一个满足条件的数据
System.out.println(list.remove(3));
System.out.println(list);
//E set(int index, E element) 用指定的元素替换此列表中指定位置的元素(可选操作)。
System.out.println(list.set(2,"ss"));
System.out.println(list);
//List<E> subList(int fromIndex, int toIndex) 返回指定的 fromIndex (包含)和 toIndex (不包括)之间的此列表部分的视图。 结束索引不包含
System.out.println(list.subList(0,2));
}
}
3.1 ListIterator迭代器的使用
public static void main(String[] args) {
List<String> list=new ArrayList();
list.add("灭霸");
list.add("钢铁侠");
list.add("蜘蛛侠");
list.add("蜘蛛侠");
ListIterator it= list.listIterator(4);
/* while (it.hasNext()){
if("灭霸".equals(it.next())){
it.add("惊奇队长");
}
}*/
//逆序
while (it.hasPrevious()){
System.out.println(it.previousIndex()+"--->"+it.previous());
}
}
1.1、ArrayList
1.特点:查询效率高,增删效率低
2.应用场景:大量查询,少量增删的场景
3.扩容机制:扩大为原数组的1.5倍,初始容量默认为10
注:定义ArraList存储自定义引用数据类型的数据时,应当重写equals与toString方法
1.2、Vector(了解)
1.特点:与ArrayList类似(向量)
2.扩容:扩容为原数组的两倍
同步问题:Vertor线程是安全的 | 同步的,ArrayList线程是不同步 |不安全的。
Javabean规范:
1.类是公共的
2.至少提供一个空结构
3.属性私有化
4.公共的访问方式
5.重写equals和toString方法
6.根据需要实现序列化接口
1.3、LinkList
1.链表结构:数据以节点为单位
1.1单链链表
数据值 | 下一个节点地址 |
1.2双向链表
上一个节点地址 | 数据值 | 下一个节点地址 |
2.特点:查询效率低,增删效率高
3.新增功能: 根据链表头尾进行操作的方法
4.listIterator 列表迭代器 : 在迭代集合中元素的同时,修改元素,可以反向,正向,指定位置开始遍历
ListIterator<String> it2 = list.listIterator(5);
System.out.println(list);
while(it2.hasPrevious()){
System.out.println(it2.previousIndex()+"-->"+it2.previous());
}
二、Set
1.特点:无序,不可重复,没有索引
不包含重复元素的集合。 更正式地说,集合不包含元素对e1和e2 ,使得e1.equals(e2)和最多一个null元素。
无序:添加的顺序与内部真实存储数据的顺序不一致
public class Class04_Set {
public static void main(String[] args) {
Set<String> set=new HashSet<>();
set.add("nihao");
set.add("哈哈");
set.add("fjdj");
set.add("123");
set.add("123");
System.out.println(set);
Iterator it= set.iterator();
while (it.hasNext()){
System.out.println(it.next());
}
}
}
2.注意: 关注set实现类的去重方式
新增工能; 无新增功能
遍历: 1)iterator() 2)foreach
2.1、TreeSet
1.TreeSet : 无序,不可重复
底层结构: 红黑树(平衡二叉树)
特点: 数据默认升序排序
应用场景: 存储多个数据中不允许重复数据,并且想要排序就可以选中使用TreeSet
新增方法: 新增了一些与比较相关的方法
2.注意: 不同类型的数据不能使用TreeSet实现排序
自定义引用数据类型如何实现默认升序排序?
定义User类型,存储多个用户对象放入TreeSet集合,是否能够成功实现排序,是否能够实现去重
自定义引用数据类型对象存储: 要求定义比较规则
自定义引用数据类型的去重: 根据比较规则的返回值做去重,返回值为0代表相同,去重
自定义引用数据类型的排序: 根据比较规则的做排序,默认升序排序,可以根据比较规则方法的实现,实现一个降序排序
比较规则:
内部比较器|自然排序 : 比较规则定义在类的内部
自定义引用数据类型实现Comparable<T>接口,重写compareTo方法,方法的内部制定当前类型数据的比较规则
根据compareTo返回值决定去重与排序
o1.compareTo(o2)
0 --> o1=o2
负数 --> o1<o2
正数 --> o1>o2
外部比较器|定制排序 : 比较规则定义在类的外部
定义一个实现类,实现Comparator接口,重写compare方法,在方法内部制定比较规则
总结:
定义TreeSet集合的时候,构造器的参数是否指定使用哪一种外部比较规则,如果没有指定外部比较规则,默认找到数据的内部比较规则
如果外部与内部比较规则都不存在,排除类型转换异常
匿名内部类用来简化没有自己作用的,使用次数比较少的,接口实现类
2.2HashSet
1.底层:是由HashMap维护的 哈希表(数组+链表+红黑树)
2.特点:查询,增删效率高,无序,去重
3.存储方式:
数组的每个元素存储一个单链表的首节点地址
1.)存储数据调用hashcode方法得到对象整数的表现形式
2.)把对象整数值进行统一的hash算法运算,得到位桶索引(数组的索引值)
3.)将数据拿到对应位桶存储(去重),如果两个数据索引相同,用equals方法与数组元素中链表的每个值进行比较,没有相同的值就进行存储(单链表存储)
三、HashMap
1.Map
Map : 键值对的集合
键值对: Key - Value
key : 唯一的,去重的,无序的 --> Set
value : 可以重复, 无序的 --> Collection
一个key只能对应一个value
一个key对应一个value,value可以为一个数组,一个集合
2.HashMap
底层结构: 哈希表(数组+链表+红黑树)
基于哈希表的Map接口的实现。并允许null值和null键。
HashMap存储机制:
数组的长度: 2的整数次幂
1.根据key调用hash方法,计算出了key的hash值 int hash = (h = key.hashCode()) ^ (h >>> 16)
2.根据hash值计算位桶的索引 : index = (n - 1) & hash 优化的算法: 帮助提高效率,尽量减少哈希碰撞,散列的分布在每一个位桶中,提高效率
3.判断数组table中对应索引位置table[index]==null,内部没有节点,当前要存储的键值对数据直接创建成为新节点new Node(hash, key, value, null)->放入数组index位桶中,作为链表头节点存在
4.不等于null,从链表头开始遍历这个链表,判断每一个节点的key是否与要存储的键值对的key相等,如果相等value覆盖,都不相等,创建新节点,加入原链表的最后
5.size++; if (++size > threshold) resize(); 判断如果>扩容临界值,进行扩容
public class Class003_HashMap {
public static void main(String[] args) {
//HashMap() 使用默认初始容量(16)和默认加载因子(0.75)构造一个空 HashMap 。
//HashMap(int initialCapacity) 使用指定的初始容量和默认加载因子(0.75)构造一个空 HashMap 。
//HashMap(int initialCapacity, float loadFactor) 使用指定的初始容量和加载因子构造一个空 HashMap 。
HashMap<Integer,String> map = new HashMap<>();
}
}
2.1TreeMap
底层结构: 红黑树
特点: 默认升序排序(key)
实现: 根据key做存储,根据做去重,根据key做排序
TreeSet底层是由TreeMap维护的
新增功能: 新增了一些与比较相关的方法
去重: key的类型要求实现内部比较规则或者TreeMap对象构造器中指定外部比较规则
优先找外部,没有外部找内部
排序去重 : 都是根据比较器实现,与equals,hashCode没有关系
四、工具类
4.1 Properties
概念:表示一组持久的属性,可以保存到流或从流中加载
属性列表中每个键及其对应的值都是一个字符串
作为配置文件使用:
1.src下定义一个xx.properties文件
2.在文件中定义键值对的数据
3.构建Properties类型的对象
4.从流中加载数据(对象名.load)--->流
4.2Collections类
概念:提供了对List、Map、Set的操作
常用方法:sort()对List容器内的元素进行升序排序
shuffle()对List容器内的元素进行随机排序
reverse()对List容器内的元素进行逆序排序
fill (List,Object) 用一个特定的对象重写整个List容器
binarySearch(List,Object) 对顺序的List容器,采用折半的方法查找对象