1. 数据结构
1.1. 什么是数据结构
数据结构是用来存储数据的结构,而使用特定数据结构,这些存放数据有特定关系
1.2. 常见的数据结构
1. 数组 ---> 查询快,增删改 慢
2. 链表 ---> 查询慢, 增删改 快
3. 队列 ---> 先进先出
4. 栈 ---> 先进后出
5. 树形结构
2. Collection
3. List 接口(可重复,有序的)
3.1. ArryList(底层数组)
- ArrayList 底层是一个数组,拥有自动扩容机制。所以--> 查询快 增删慢
- 可重复、有序的 ,默认容量10。
ArrayList 的默认容量 ->10
3.1.1. ArrayList 的构造方法
- ArrayList() :构造一个初始容量为 10 的空集合。
- ArrayList(Collection<? extends E> c) :用于创建一个ArrayList对象,并将指定集合(Collection类型集合)中的元素添加到该ArrayList中。
- ArrayList(int initialCapacity) : 构造具有指定初始容量的空列表。
3.1.2. ArrayList 的常用方法
具体看API
- boolean add(E e) :将指定的元素追加到此列表的末尾。
- void add(int index, E element) :在此列表中的指定位置插入指定的元素。
- E get(int index) :返回此列表中指定位置的元素。
- E remove(int index) :删除该列表中指定位置的元素。
- boolean remove(Object o) :从列表中删除指定元素的第一个出现(如果存在)。
- int size() :返回此列表中的元素数。
- void clear() :从列表中删除所有元素。
3.2. LinkList (底层链表)
底层 双向链表结构, 查询慢,增删 快。
链表底层没有 容量
1. 链表 是由多个 节点 合成的。
2. 节点 --> ①数据 ②下一个节点的内存地址 ③ 上一个节点的内存地址
3. previous 为空 该节点为链表的 头,next 为空 该节点为链表的 尾。
4. 通过 链表头,查询链表头。
Node temp = head;
While(temp.next != null ){
temp=temp.next
}
3.3. 遍历
list 接口遍历方式有四种:
- for 循环
- forech 循环
- iterable 迭代器
Iterator iterator = arrayList.iterator(); // 掉方法获取迭代器;collection父类中实现了Iterable接口。
- boolean hasNext():判断是否有下一个元素,如果返回true表示有下一个;
- Object next():调用一次获得一个元素(每调用一次指针会向后移动一个);注意:所以一个迭代器只能用一次,想要再次使用需要重写获取新的迭代器。
- listIterable 是双向迭代器。’List 特有的迭代器
3.3.1. List 为什么能用迭代器?
因为collection中实现了Iterable接口
- iterable 是单迭代器,‘
- listIterable 是双向迭代器,是List 特有的迭代器
4. Set(不重复)
Set 集合框架的特点:
- 不包含重复元素的集合
- 没有带索引的方法,所有不能使用普通的for循环遍历
4.1. Set 如何验证 重复性(**)
- 将添加进去的元素通过 equals 和 hashcode 判断是否相等。
- equals 相等 hashcode一定相等。
- hashcode 相等 equals 不一定相等。
4.2. HashSet(无序列,不重复)
无序的,无重复的。
哈希值:是JDK根据对象的地址或者字符串或者数字算出来的int类型的数值
4.2.1. HashSet 集合特点
- 底层数据结构 是 哈希表
- 对集合的迭代顺序不做任何保证,也就是说不保证 存储和取出的元素顺序一致。
- 没有带索引的方法,所以不能使用普通 for 循环遍历。
- 由于是 Set 集合,所以是不能包含重复元素的集合。
4.2.2. HashSet 集合添加一个元素的过程
4.3. LinkedHashSet
有序的,无重复的。
4.3.1. LinkedHashSet 集合特点
- 哈希表 和 链表 实现的set接口,具有可预测的迭代次序。
- 由 链表保证元素有序,也就是说 元素的存储和取出顺序是一致的。
- 由 哈希表保证元素唯一,没有重复的元素。
4.4. TreeSet (不可重复,排序)
- 不可重复,排序
- TreeSet是一种可排序的、不允许重复元素的集合,底层采用红黑树实现,具有较高的插入、删除和查找效率。
- 存储的类型必须一致。
cn.ronghuanet._02set.User cannot be cast to java.lang.Comparable
4.4.1. TreeSet 的结构(存储原理分析)
- TreeSet 内部是按照大小进行排序的,大小有对象与对象之间比较进行决定的。
- 设计TreeSet之前:Java设计了一个接口Comparable接口,其中提供了对象之间比较的方法CompareTo。
- TreeSet 会调用对象的 CompareTo 方法,比较对象,所以我们放入的对象需实现Comparable。
String 重写了compareTo
4.5. 自然排序与定制排序(比较器)
4.5.1. 自然排序 comparable
什么是自然排序
- 例如:大家排队,按照高矮个排队,那么同学们自己相互之间就能进行对比,每个对象具备自我比较判断的能力,称之为自然排序
- 此接口强行对实现它的每个类的对象进行整体排序。这种排序被称为类的自然排序,类的 compareTo方法被称为它的自然比较方法。
- 如果一个类实现了Comparable接口,可以认为这个类的对象具有自然排序的能力(本质就是这个对象可以调用比较的方法compareTo)。
案例
类实现 comparable 接口重写 compareTo 方法
public class User implements Comparable{
private String name;
private Integer age;
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
User user = (User) o;
return Objects.equals(name, user.name) &&
Objects.equals(age, user.age);
}
@Override
public int hashCode() {
return Objects.hash(name, age);
}
@Override
public int compareTo(Object o) {
User user = (User)o;
if (this.age > user.age){
return -1;
}else if (this.age < user.age){
return 1;
}else{
return this.name.compareTo(user.name);
// if (this.name.length()>user.name.length()){
// return -1;
// }else{
// return 1;
// }
}
}
}
TreeSet treeSet3 = new TreeSet();
treeSet3.add(new User("zs",10));
treeSet3.add(new User("lss",10));
treeSet3.add(new User("zll",13));
treeSet3.add(new User("myyh",42));
treeSet3.add(new User("yyxzz",15));
System.out.println(treeSet3);
4.5.2. 定制排序(比较器)Comparator
什么是定制排序
定制排序,相当于给容器提供了一个裁判:例如操场就是一个容器,那么体育老师就是这个裁判,每个同学进入操场同学们相互之间可以比较谁比较帅,或者不可以比较谁帅都可以,有了老师这个裁判,老师可以负责比较每一位同学。
为什么需要定制排序
- 原来的比较规则不符合所有人的使用需求。
- 不存在比较规则的对象,无法放入容器,可以给容器提供定制比较器。
定制排序如何实现
Comparator 是一个比较器的接口(标准),必须得有进行比较的方法 :compare(Object o1,Object o2)
案例
/**
* 定制排序 - 自己去写一个 比较器
*/
public class DogComparator implements Comparator {
@Override
public int compare(Object o1, Object o2) {
Dog dog1 = (Dog)o1;
Dog dog2 = (Dog)o2;
if (dog1.age > dog2.age){
return 1;
}else if (dog1.age < dog2.age)
return -1;
else{
return dog1.name.compareTo(dog2.name);
}
}
}
TreeSet dogTree = new TreeSet(new DogComparator());
dogTree.add(new Dog("zs",10));
dogTree.add(new Dog("lss",10));
dogTree.add(new Dog("zll",13));
dogTree.add(new Dog("myyh",42));
dogTree.add(new Dog("yyxzz",15));
System.out.println(dogTree);
4.5.3. TreeSet排序 判断重复的标准小结
1、如果采用的是自然排序调用对象的compareTo方法,如果返回0 表示相等;
大于且返回正数,升序排列 => 小于且返回负数,升序排列 对应
大于且返回负数,降序排列 => 小于且返回正数,降序排列对应
2、如果使用的定制排序(比较器),调用比较器的方法compare 返回0 表示相等;
大于且返回正数,升序排列 => 小于且返回负数,升序排列 对应
大于且返回负数,降序排列 => 小于且返回正数,降序排列对应
5. 注意:
集合框架中存储的元素全部都是对象,从1.5开始支持自动装箱拆箱,所以基本数据类型也可以直接添加。