目录
1. 集合
1.1 List
1.1.1 LinkedList
1.1.1.1 基本使用
LinkedList : 底层是一个双链表, 不是连续存储, 只是可以找到下一个元素的地址而已, 所以进行
添加和删除操作效率较高, 但是查询效率较低, 因为只能从第一个挨个查找
区别于ArrayList(底层是Object数组, 优缺点正好相反)
add和offer的区别 : 返回false的原因有无限制
add : 当且仅当该元素已经存在时返回false
offer : 可出于任何原因返回false,例如 队列已满
import java.util.LinkedList;
public class Collection_01 {
public static void main(String[] args) {
LinkedList linkedList = new LinkedList();
// 尾部添加
linkedList.add("11");
linkedList.addLast("22");
linkedList.offerLast("xx");
// 首部添加
linkedList.addFirst("xxx");
linkedList.offerFirst("xxx");
// 根据索引获取
linkedList.get(1);
// 获取第一个
linkedList.getFirst();
// 获取最后一个
linkedList.getLast();
// 删除第一个
linkedList.removeFirst();
// 删除最后一个
linkedList.removeLast();
}
}
1.1.1.2 底层实现
1.1.1.2.1 节点类
链表由节点构成,因为是双向链表,所以节点中有三个属性
1 保存的数据 Object
2 下一个节点对象 节点类型
3 上一个节点对象 节点类型
1.1.1.2.2 LinkedList类
为了首尾添加效率更高,在LinkedList类中保存了首节点和尾结点
1.1.1.2.3 添加-add
添加主代码
尾部添加
首部添加
1.1.1.2.4 获取-get
校验越界方法
1.2 set和排序
Set特性 无序不可重复
无序 : 指的是添加顺序不保证有序
不可重复 : 不能添加重复数据
TreeSet : 底层是红黑树,添加的元素会按照一定格式进行自动排序
比如 数字 : 默认升序 , 12345
字符串 : 默认按照每一位ASCII码值进行排序
1 2 3 4 5 6 7 8 9 10
1 10 2 3 4 5 6 7 8 9
Date : 自然日期,昨天,今天明天
HashSet : 底层是 HashMap,而HashMap底层是散列表
HashSet 是Map中的key部分
1.2.1 TreeSet
TreeSet : 会自动排序,是因为向treeSet中添加的数据,都有比较器,因此我们如果要添加没有比较器的对象或者自定义的对象时,会出错,另外 因为排序需要比较,所以只能添加同类型数据
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import java.util.TreeMap;
import java.util.TreeSet;
public class Collection_02_Set {
public static void main(String[] args) {
// Set set = new TreeSet();
Set set = new HashSet();
// 重复后,不添加
// 添加会调用对象的equals方法,进行比较,重复不添加
set.add("a");
set.add("a");
set.add("a");
set.add("a");
set.add("a");
set.add("1");
set.add("b");
set.add(23123);
// 删除,根据内容删除
set.remove("a");
// 没有修改和查询
System.out.println(set);
// 个数
System.out.println(set.size());
// 判断是否为空(个数是否为0)
System.out.println(set.isEmpty());
// 判断是否包含某个元素
System.out.println(set.contains("x"));
// 清空
set.clear();
//遍历
for (Object object : set) {
System.out.println(object);
}
int[] arr = {};
//for(变量类型 变量 : 每一个数据)
for (int i : arr) {
}
}
}
1.2.2 Comparable
比较器之 Comparable , 被添加的元素,需要实现 Comparable 接口,并覆写 接口中的 compareTo()方法
compareTo方法返回值代表排序规则, 添加元素时,会用要添加的元素对象调用compareTo方法,把集合中的元素传入进行比较 如果是0 ,说明重复,不添加, 如果小于0,说明要添加的元素小,往前放, 如果大于0 ,说明要添加的元素大,往后放
import java.util.Set;
import java.util.TreeSet;
public class Collection_04_Set {
public static void main(String[] args) {
Set set = new TreeSet();
set.add(new Student("张三1",18));
set.add(new Student("张三2",19));
set.add(new Student("张三3",17));
System.out.println(set);
System.out.println(set.size());
}
}
里面用了compareTo方法,考虑好输入数据和数组中数据的位置, 返回值为负数时,会将输入的数据往前放, 反之往后放, 考虑方法结果是升序还是降序
public class Student implements Comparable{
private String name;
private int age;
public Student(String name, int age) {
super();
this.name = name;
this.age = age;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Student(String name) {
super();
this.name = name;
}
@Override
public String toString() {
return "Student [name=" + name + ", age=" + age + "]";
}
@Override
public int compareTo(Object o) {
// this : 当前要被添加的元素
// o : 集合中的元素
if (o instanceof Student) {
Student s1 = (Student) o;
// 19 17
// 升序
// return this.age - s1.age;
return s1.age - this.age;
}
return 0;
}
}
1.2.3 Comparator
Comparator : 比较器类,要添加的元素并不需要实现这个借口
1 比如 Integer中 默认有比较方法.并且是升序,假如我们想要降序的时候,此时没办法修改源码,所以可以通过Comparator来重新定义排序规则
2 我们想保存的数据,不能排序(没有实现Comparable接口),但是这个类也不是我们写的,比如
Object,想要把Object对象保存在treeSet中, 我们没有办法去修改源码,还是需要Comparator 来进行比较
当保存的元素不能排序(没有实现Comparable接口)时, 或者 , 排序规则不符合我们的需求时,均使用Comparator 来解决
并且 当 Comparator 比较器 和 Comparable比较器 同时存在时,Comparator 优先级高于 Comparable
对修改关闭,对扩展开放
通常用匿名内部类
自己创建的类,可以修改源码,通常使用Comparable ; 反之不能修改源码时使用Comparator
以下代码用了两种方式 :
匿名内部类和调用接口
import java.util.Comparator;
import java.util.Set;
import java.util.TreeSet;
public class Collection_05_Set {
public static void main(String[] args) {
//调用接口将 Test_01 调入
// Set set = new TreeSet(new Test_01());
// 匿名内部类
Set set = new TreeSet(new Comparator() {
@Override
public int compare(Object o1, Object o2) {
if (o1 instanceof Integer && o2 instanceof Integer) {
Integer i1 = (Integer) o1;
Integer i2 = (Integer) o2;
// 10 9
return i2 - i1;
}
return 0;
}
});
set.add(1);
set.add(11);
set.add(2);
set.add(5);
set.add(15);
System.out.println(set);
}
}
class Test_01 implements Comparator {
@Override
public int compare(Object o1, Object o2) {
// o1 是要添加的元素
// System.out.println(o1);
// o2 是集合中的元素
// System.out.println(o2);
if (o1 instanceof Integer && o2 instanceof Integer) {
Integer i1 = (Integer) o1;
Integer i2 = (Integer) o2;
// 10 9
return i2 - i1;
}
// 0 说明相等,不添加
// 小于0 说明要添加的元素比集合中的元素小,往前放
// 大于0 说明要添加的元素比集合中的元素大,往后放
return 0;
}
}
1.2.4 List排序
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
public class Collection_07_ListSort {
public static void main(String[] args) {
List list = new ArrayList();
list.add(1);
list.add(11);
list.add(12);
list.add(2);
// 使用API进行排序,会调用 元素的compareTo 方法进行排序
Collections.sort(list);
// 如果 要添加的元素,排序规则不符合我们需求,或,元素没有 compareTo方法,则使用Comparator
Collections.sort(list, new Comparator() {
@Override
public int compare(Object o1, Object o2) {
if (o1 instanceof Integer && o2 instanceof Integer) {
Integer i1 = (Integer) o1;
Integer i2 = (Integer) o2;
return i2 - i1;
}
return 0;
}
});
// 使用集合自身的排序,需要传入 Comparator 比较器进行比较
list.sort(new Comparator() {
@Override
public int compare(Object o1, Object o2) {
if (o1 instanceof Integer && o2 instanceof Integer) {
Integer i1 = (Integer) o1;
Integer i2 = (Integer) o2;
return i1 - i2;
}
return 0;
}
});
System.out.println(list);
}
}
1.2.5 总结
* Comparable : 如果treeSet中保存我们自己定义的类型的时候,使用Comparable
*
* Comparator : 如果treeSet中保存的不是我们写的类型的时候,就要使用Comparator来指定排序规则
* 比如 Integer 默认是升序排序,假如我们需要降序排序,我们只能使用 Comparator,因为我们不可能去更改Integer的源码
* 但此时 Integer中是有Comparable接口的实现的,等于两个比较都存在,但是Comparator优先级高,
* 所以会按照我们定义的规则进行排序
* 开闭原则 : 对修改关闭,对扩展开发
1.3 Set
List 有序可重复
ArrayList : 查询快,底层是数组
LinkedList : 添加删除快,底层是双向链表
Set 无序不可重复
HashSet : 底层是散列表
TreeSet : 底层是红黑树,元素必须有序
Map 无序,key不能重复,value能重复,保存映射关系
HashMap : 底层是散列表
TreeMap : 底层是红黑树,元素必须有序
1.3.1 HashSet使用
方法与TreeSet一致, 代码完全可以复用