01. List接口的特点
/*
List接口是Collection下面的一个子接口。
List接口有三个特点:
1. 有序。(有序不是按顺序排序, 有序指的是怎么存,就怎么取)
2. 有索引。 (可以根据索引获取元素)
3. 可重复 (可以存放重复的元素)
List是接口,如果要用,需要使用实现类,最常用的实现类是ArrayList
*/
public class Demo01List {
public static void main(String[] args) {
//定义一个集合
List<String> list = new ArrayList<>();
//添加元素
list.add("貂蝉");
list.add("西施");
list.add("王昭君");
//输出集合
//1. 有序。
System.out.println("list:" + list);
//2. 有索引。 (可以根据索引获取元素)
System.out.println(list.get(1));
//3. 可重复 (可以存放重复的元素)
list.add("西施");
list.add("西施");
list.add("西施");
list.add("西施");
list.add("西施");
list.add("西施");
list.add("西施");
list.add("西施");
System.out.println("list:" + list);
}
}
02. List接口中的常见方法
/*
List接口中常见的方法
public void add(int index, E element) : 将指定的元素,添加到该集合中的指定位置上。
(常用)public E get(int index) :返回集合中指定位置的元素。
public E remove(int index) : 移除列表中指定位置的元素, 返回的是被移除的元素。
public E set(int index, E element) :用指定元素替换集合中指定位置的元素,返回值的更新前的元素。
*/
public class Demo02ListMethod {
public static void main(String[] args) {
method3();
}
/*
public E set(int index, E element): 使用参数element替换掉集合index位置上的元素。返回的是被替换掉的元素
*/
public static void method3() {
//定义集合
List<String> list = new ArrayList<>();
//添加元素
list.add("hello");
list.add("world");
list.add("java");
//输出集合
System.out.println("list:" + list);
//把集合中的java替换为php
String str = list.set(2, "php");
System.out.println("list:" + list);
System.out.println("str:" + str);
}
/*
public E remove(int index) : 移除列表中指定位置的元素, 返回的是被删除的元素。
*/
public static void method2() {
//定义集合
List<String> list = new ArrayList<>();
//添加元素
list.add("hello");
list.add("world");
list.add("java");
//输出
System.out.println("删除前:" + list);
//删除索引为1的元素
String str = list.remove(1);
System.out.println("删除后:" + list); //[hello, java]
System.out.println("str:" + str); //world
}
/*
public void add(int index, E element): 在指定索引位置添加元素。
(常用)public E get(int index) :返回集合中指定位置的元素。
*/
public static void method() {
//定义集合
List<String> list = new ArrayList<>();
//添加元素
list.add("hello");
list.add("world");
list.add("java");
//输出集合
System.out.println("list:" + list); //[hello, world, java]
//向集合中索引为1的位置插入一个元素,插入 "詹姆斯高斯林"
list.add(1, "詹姆斯高斯林");
System.out.println("list:" + list); //[hello, 詹姆斯高斯林, world, java]
//使用get,获取索引为0的元素
System.out.println("索引为0的元素是:" + list.get(0));
}
}
03. 栈结构的特点
04. 队列结构的特点
05. 数组结构的特点
06. 链表结构的特点
07. 红黑树
08. ArrayList的特点
ArrayList 是在采用数组保存数据。
特点: 查询快, 增删慢
ArrayList是我们以后用的最多的集合。
09. LinkedList的特点
LinkedList也是List接口下面的一个实现类。
LinkedList内部是在使用链表(双向链表)保存数据
特点: 查询慢,增删快
10. LinkedList独有的方法
/*
常见方法(LinkedList特有的方法):
public void addFirst(E e) :将指定元素插入此列表的开头。
public void addLast(E e) :将指定元素添加到此列表的结尾。
public E getFirst() :返回此列表的第一个元素。
public E getLast() :返回此列表的最后一个元素。
public E removeFirst() :移除并返回此列表的第一个元素。
public E removeLast() :移除并返回此列表的最后一个元素。
public E pop() :从此列表所表示的堆栈处弹出一个元素。
public void push(E e) :将元素推入此列表所表示的堆栈。
*/
public class Demo04LinkedList {
public static void main(String[] args) {
method4();
}
/*
public E pop(): 弹出。 删除集合中的第一个元素并将该元素返回。
public void push(E e): 压入。 向集合的第一个位置添加元素
*/
public static void method4() {
//定义集合
LinkedList<String> list = new LinkedList<>();
//调用add方法添加元素
list.add("hello");
list.add("world");
list.add("java");
System.out.println("操作前list:" + list); //[hello, world, java]
// public E pop(): 弹出。 删除集合中的第一个元素并将该元素返回。
//String str = list.pop();
//System.out.println("操作后list:" + list); //[world, java]
//System.out.println("str:" + str); //hello
//public void push(E e): 压入。 向集合的第一个位置添加元素
list.push("php");
System.out.println("操作后list:" + list); //[php, hello, world, java]
}
/*
public E removeFirst() :删除集合中的第一个元素, 返回被删除的元素
public E removeLast() :删除集合中的最后一个元素, 返回被删除的元素
*/
public static void method3() {
//定义集合
LinkedList<String> list = new LinkedList<>();
//调用add方法添加元素
list.add("hello");
list.add("world");
list.add("java");
System.out.println("删除前:" + list); //[hello, world, java]
//public E removeFirst() :删除集合中的第一个元素
//String str = list.removeFirst();
//System.out.println("删除后:" + list); //[world, java]
//System.out.println("str:" + str); //hello
//public E removeLast() :删除集合中的最后一个元素
String str = list.removeLast();
System.out.println("删除后:" + list); //[hello, world]
System.out.println("str:" + str); //java
}
/*
public E getFirst() :获取集合中的第一个元素
public E getLast() :获取集合中的最后一个元素
*/
public static void method2() {
//定义集合
LinkedList<String> list = new LinkedList<>();
//调用add方法添加元素
list.add("hello");
list.add("world");
list.add("java");
System.out.println("获取首个元素:" + list.getFirst()); //hello
System.out.println("获取尾部元素:" + list.getLast()); //java
}
/*
public void addFirst(E e) : 向集合首个位置添加元素
public void addLast(E e) : 向集合尾部添加元素
*/
public static void method() {
//定义集合
LinkedList<String> list = new LinkedList<>();
//调用add方法添加元素
list.add("hello");
list.add("world");
list.add("java");
System.out.println("list:" + list); //[hello, world, java]
//调用addFirst向集合的最开始添加元素
list.addFirst("php");
System.out.println("list:" + list); //[php, hello, world, java]
//public void addLast(E e) : 向集合尾部添加元素
list.addLast("python");
System.out.println("list:" + list); //[php, hello, world, java, python]
}
}
11. Set 接口的特点
/*
Set接口是Collection下面的另一个子接口。
Set接口有三个特点:
1. 无序(怎么存,不一定怎么取)
2. 没有索引(不能根据索引获取元素)
3. 不可重复(不能存放重复元素)
Set是一个接口,如果要用,需要使用实现类, Set接口下面最常用的实现类是HashSet
*/
public class Demo01Set {
public static void main(String[] args) {
//定义一个Set集合
Set<String> set = new HashSet<>();
//添加元素
set.add("张三丰");
set.add("张无忌");
set.add("灭绝师太");
set.add("金花婆婆");
//输出
//1. 无序(怎么存,不一定怎么取)
System.out.println(set); //[灭绝师太, 张三丰, 张无忌, 金花婆婆]
//2. 没有索引(不能根据索引获取元素)
//System.out.println(set.get(1));
//3. 不可重复(不能存放重复元素)
set.add("灭绝师太");
set.add("灭绝师太");
set.add("灭绝师太");
set.add("灭绝师太");
set.add("灭绝师太");
set.add("灭绝师太");
System.out.println(set);
}
}
12. HashSet的介绍以及遍历
/*
如果要对Set集合进行遍历, 要么使用迭代器, 要么使用增强for。
强烈推荐:增强for
HashSet是Set下面最常用的实现类,满足Set接口所有的特点。
*/
public class Demo02Set {
public static void main(String[] args) {
//定义集合
Set<String> set = new HashSet<>();
//添加元素
set.add("hello");
set.add("world");
set.add("java");
set.add("php");
//对集合进行遍历
for(String s : set) {
//s表示集合中的每一个元素
System.out.println(s);
}
}
}
13. 对象和哈希值介绍以及如何获取到对象的哈希值
/*
哈希值就是一个int数字, 我们可以把哈希值看出对象的一个标识(特征码)
在Object中,有一个方法叫做hashCode,可以获取对象的哈希值。
Object中的hashCode的哈希值是根据地址值计算的。
如果想要自己定义哈希值的计算规则,可以重写hashCode方法。
注意: 哈希值是对象的一个标识,但并不是一个唯一的标识,哈希值允许重复。
总结:
1. 哈希值是对象的一个特征码, 是一个int数字, 对象的哈希值允许重复。
2. 调用对象的hashCode可以获取对象的哈希值,如果要自己定义哈希值的计算规则,那么需要重写hashCode方法。
*/
public class Demo01HashCode {
public static void main(String[] args) {
//创建Person对象
Person p = new Person("柳岩", 38);
//调用对象的hashCode,获取对象的哈希值。
System.out.println(p.hashCode());
Person p2 = new Person("柳岩", 38);
System.out.println(p2.hashCode());
Person p3 = new Person("白百合", 20);
System.out.println(p3.hashCode());
}
}
public class Person {
private String name;
private int age;
//alt + insert
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Person person = (Person) o;
if (age != person.age) return false;
return name != null ? name.equals(person.name) : person.name == null;
}
@Override
public int hashCode() {
int result = name != null ? name.hashCode() : 0;
result = 31 * result + age;
return result;
}
//重写hashCode,改变哈希值的计算规则
//对象的哈希值一般根据属性去计算。如果两个对象的属性完全相同,那么哈希值应该一样。
/*
public int hashCode() {
return name.hashCode() + age;
}
*/
public Person() {
}
public Person(String name, int age) {
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
14. 哈希表的介绍
15. HashSet判断唯一性的原因
16. HashSet存储自定义对象
/*
HashSet判断唯一性的原理
1. 先比较两个对象的哈希值。
如果两个对象的哈希值不同,那么肯定不是同一个对象。
如果两个对象的哈希值相同,不一定是同一个对象。
2. 如果两个对象的哈希值相同,那么还需要调用equals方法进行比较。
如果调用equals得到的结果是true,那么表示是同一个对象
如果调用equals得到的结果是false,那么表示不是同一个对象
要求: 使用HashSet存储Person对象, 并要求保证唯一性(如果两个对象的属性完全相同,那么就看成同一个对象)
结论:如果使用HashSet存储自定义对象,并且要保证唯一性(如果两个对象的属性完全相同,那么就看成同一个对象),那么需要重写hashCode和equals方法
*/
public class Demo01HashSet {
public static void main(String[] args) {
//定义HashSet,用来保存Person
Set<Person> set = new HashSet<>();
//添加元素
set.add(new Person("刘德华", 12));
set.add(new Person("张学友", 22));
set.add(new Person("郭富城", 32));
set.add(new Person("刘德华", 12));
//遍历并输出集合中的每一个元素
for(Person p : set) {
System.out.println(p);
}
}
}
public class Person {
private String name;
private int age;
//alt + insert
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Person person = (Person) o;
if (age != person.age) return false;
return name != null ? name.equals(person.name) : person.name == null;
}
@Override
public int hashCode() {
int result = name != null ? name.hashCode() : 0;
result = 31 * result + age;
return result;
}
@Override
public String toString() {
return "Person{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
public Person() {
}
public Person(String name, int age) {
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
17. LinkedHashSet的特点
/*
Set接口中还有一个实现类叫做LinkedHashSet
LinkedHashSet内部除了有一个哈希表之外,还有一个链表,链表的作用是保证【有序】。
Set接口是无序的,但是他不能保证所有的实现类都无序。
*/
public class Demo01LinkedHashSet {
public static void main(String[] args) {
//定义集合
Set<String> set = new LinkedHashSet<>();
//添加元素
set.add("hello");
set.add("world");
set.add("java");
set.add("php");
//输出集合
System.out.println(set);
}
}
18. Collections中的shuffle方法
/*
Collections 是一个工具类,是操作集合的工具类。
常见方法:
public static void shuffle(List<?> list) :打乱集合顺序
*/
public class Demo01Collections {
public static void main(String[] args) {
//定义集合
ArrayList<String> list = new ArrayList<>();
//添加元素
list.add("aa");
list.add("bb");
list.add("cc");
list.add("dd");
//调用shuffle方法,打乱顺序
Collections.shuffle(list);
//输出
System.out.println(list);
}
}
19. Collections的自然排序
/*
在Collections中,有一个方法,可以对集合中的内容进行排序。
public static void sort(List list) :对集合中的内容进行排序
要使用该sort方法排序的集合,对应的泛型必须实现Comparable接口。
当一个类实现了Comparable接口后,就表示该类的对象具备了比较的功能,这种排序叫做自然排序
公式: 升序就是我减他。
*/
public class Demo02Collections {
public static void main(String[] args) {
//定义集合,保存数字
ArrayList<Integer> numList = new ArrayList<>();
//添加数字
numList.add(200);
numList.add(100);
numList.add(300);
//调用sort方法,进行排序
Collections.sort(numList);
System.out.println("numList:" + numList);
System.out.println("=====================================");
//定义集合保存字符串
ArrayList<String> strList = new ArrayList<>();
strList.add("bbb");
strList.add("aaa");
strList.add("ccc");
//调用sort方法,对保存字符串的集合进行排序
Collections.sort(strList);
System.out.println("strList:" + strList);
System.out.println("=====================================");
//定义集合,保存Person
ArrayList<Person> personList = new ArrayList<>();
//添加Person对象
personList.add(new Person("柳岩", 36));
personList.add(new Person("大幂幂", 26));
personList.add(new Person("金星", 38));
//对保存Person对象的集合进行排序
Collections.sort(personList);
System.out.println("personList:" + personList);
}
}
public class Person implements Comparable<Person>{ //类实现Comparable接口后,就表示该类的对象具备了比较的功能。
private String name;
private int age;
/*
当我们使用Collections的sort方法对集合中的对象进行排序时, 系统会自动调用compareTo比较两个对象谁大谁小。
比较的是调用者对象和参数对象。
如果compareTo结果是正数,那么就表示调用者对象大于参数对象
如果结果是0,表示两个对象相等
如果compareTo结果是负数,那么就表示调用者对象小于参数对象。
如果要排序公式:
升序就是我(调用者)减他(参数)
要根据什么排序,就使用什么属性相减。
*/
@Override
public int compareTo(Person o) {
return this.getAge() - o.getAge();
}
@Override
public String toString() {
return "Person{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
public Person() {
}
public Person(String name, int age) {
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
20. Collections中的比较器排序
/*
Collections中还有一个sort方法,可以进行比较器排序
public static void sort(List list,Comparator c): 第一个参数表示要排序的集合,第二个参数表示比较器。
如果一个类没有实现Comparable接口,那么表示该类的对象并不具备自己比较的功能,那么他们就不能自己排序。
此时我们可以找一个法官帮他们去比较, 这个法官就是比较器。
Comparator表示比较器。
小结:
自然排序指的是对象本身具备比较的功能,所以可以使用sort方法直接排序。 (Comparable)
比较器排序指的是对象并不具备比较的功能,所以调用sort方法时还需要传递一个比较器 (Comparator)。
*/
public class Demo03Collections {
public static void main(String[] args) {
//定义集合
ArrayList<Student> list = new ArrayList<>();
//添加Student对象
list.add(new Student("张三", 13));
list.add(new Student("李四", 10));
list.add(new Student("王叔叔", 15));
//使用sort方法进行排序
Collections.sort(list, new Rule());
System.out.println("list:" + list);
}
}
public class Student {
private String name;
private int age;
@Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
public Student() {
}
public Student(String name, int age) {
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
/*
Comparator 表示比较器, 所以当Rule类实现该接口后,这个类表示的也是比较器
*/
public class Rule implements Comparator<Student>{
/*
当使用Collections的sort方法进行比较器排序时,内部会调用compare方法比较两个对象(o1和o2)
如果compare方法返回值为正数,那么就表示第一个对象大于第二个对象。
如果结果是0,那么表示两个对象相等。
如果compare方法返回值为负数,那么就表示第二个对象大于第一个对象。
如果要排序,公式为:
升序就是一(第一个参数)减二(第二个参数)
*/
@Override
public int compare(Student o1, Student o2) {
return o1.getAge() - o2.getAge(); //根据学生的年龄升序排序。
}
}