1。 Set集合概述和特点
总结:
* Set集合的特点
* 不允许存储重复的元素
* 没有索引
Set集合的基本使用
new HashSet<>();
2.哈希值
总结:
* 哈希值简介
* 用于计算存储元素的位置的. 提高存储元素和取出元素的效率的
* 如何获取哈希值
* hashCode()
* 哈希值的特点
* 同一个对象的哈希值是一样的
* 默认情况下,不同的对象的哈希值是不一样的,重写hashCode就能达到不同的对象的哈希值是一样的
3.HashSet集合的特点
* 无序(存储的顺序和取出的顺序有可能是不一致的)
* 不允许存储重复的元素
* 没有索引
数据结构:
JDK8之前: 哈希表(数组 + 链表)
JDK8之后: 哈希表(数组 + 链表 + 红黑树)
4.HashSet集合保证元素唯一性的原理
* 首先计算该元素的哈希值(hash()),在哈希表中找有没有相同的哈希值
* 如果没有相同的哈希值,认定为这个元素不是一个重复的元素,添加到哈希表中
* 如果有相同的哈希值,必须再调用equals方法判断相同的哈希值的内容是否是一样的
* 如果内容一样: 认定为这个元素就是一个重复的元素,不存储
* 如果内容不一样:认定为这个元素不是一个重复的元素,存储到哈希表中
* 结论:
要想判断一个元素是否是唯一的,必须重写hashCode和equals方法
5.LinkedHashSet集合特点
* 有序(存储的顺序和取出的顺序是一致的)
* 不允许存储重复的元素
* 没有索引
数据结构:
数组+链表 + 链表 ==> 数组 + 双向链表
6.TreeSet集合的特点:
* 有序(按照一定的规则进行排序,形成一定顺序的数据)
* 不允许存储重复的元素
* 没有索引
数据结构:
二叉树 --> 红黑树
TreeSet构造方法
* TreeSet(): 按照自然顺序进行排序
* TreeSet(Comparator comparator) : 按照比较器进行排序
自然排序Comparable的使用
* 案例需求
存储学生对象并遍历,创建TreeSet集合使用无参构造方法
要求:按照年龄从小到大排序,年龄相同时,按照姓名的字母顺序排序
* 实现步骤
用TreeSet集合存储自定义对象,无参构造方法使用的是自然排序对元素进行排序的
自然排序,就是让元素所属的类实现Comparable接口,重写compareTo(T o)方法
重写方法时,一定要注意排序规则必须按照要求的主要条件和次要条件来写
案例代码:
public class TreeSetDemo02 {
public static void main(String[] args) {
//创建集合对象
TreeSet<Student> ts = new TreeSet<Student>();
//创建学生对象
Student s1 = new Student("xishi", 29);
Student s2 = new Student("wangzhaojun", 28);
Student s3 = new Student("diaochan", 30);
Student s4 = new Student("yangyuhuan", 33);
Student s5 = new Student("linqingxia",33);
Student s6 = new Student("linqingxia",33);
//把学生添加到集合
ts.add(s1);
ts.add(s2);
ts.add(s3);
ts.add(s4);
ts.add(s5);
ts.add(s6);
//遍历集合
for (Student s : ts) {
System.out.println(s.getName() + "," + s.getAge());
}
}
}
public class Student implements Comparable<Student> {
private String name;
private int age;
@Override
public int compareTo(Student s) {
// return 0; 表示比较的两个对象相等
// return 1; 表示的是按照升序排序
// return -1; 表示的是按照降序排序
//按照年龄从小到大排序
// int num = this.age - s.age;
// 按照年龄从大到小排序
int num = s.age - this.age; // 主要条件
// s.name.length() - this.name.length();
// s.name.charAt(0) - this.name.charAt(0);
//年龄相同时,按照姓名的字母顺序排序
// 次要条件
int num2 = num == 0 ? this.name.compareTo(s.name) : num;
return num2;
}
}
7.比较器排序Comparator的使用
* 案例需求
存储学生对象并遍历,创建TreeSet集合使用带参构造方法
要求:按照年龄从小到大排序,年龄相同时,按照姓名的字母顺序排序
* 实现步骤
用TreeSet集合存储自定义对象,带参构造方法使用的是比较器排序对元素进行排序的
比较器排序,就是让集合构造方法接收Comparator的实现类对象,重写compare(T o1,T o2)方法
重写方法时,一定要注意排序规则必须按照要求的主要条件和次要条件来写
案例代码:
public class TreeSetDemo {
public static void main(String[] args) {
//创建集合对象
// 先定义一个Comparator实现类 重写compare方法,在创建TreeSet的时候,将omparator实现类的对象给这个构造
TreeSet<Student> ts = new TreeSet<Student>(new ComparatorImpl());
//创建学生对象
Student s1 = new Student("xishi", 29);
Student s2 = new Student("wangzhaojun", 28);
Student s3 = new Student("diaochan", 30);
Student s4 = new Student("yangyuhuan", 33);
Student s5 = new Student("linqingxia",33);
Student s6 = new Student("linqingxia",33);
//把学生添加到集合
ts.add(s1);
ts.add(s2);
ts.add(s3);
ts.add(s4);
ts.add(s5);
ts.add(s6);
//遍历集合
for (Student s : ts) {
System.out.println(s.getName() + "," + s.getAge());
}
}
}
class ComparatorImpl implements Comparator<Student>{
public int compare(Student s1, Student s2) {
//this.age - s.age
//s1,s2 s1 - s2 按照升序进行排序 s2 - s1 : 按照降序进行排序
int num = s1.getAge() - s2.getAge();
int num2 = num == 0 ? s1.getName().compareTo(s2.getName()) : num;
return num2;
}
}
public class Student {
private String name;
private int age;
}
8.成绩排序案例【应用】
* 案例需求
* 用TreeSet集合存储多个学生信息(姓名,语文成绩,数学成绩),并遍历该集合
* 要求:按照总分从高到低出现
public class TreeSetDemo {
public static void main(String[] args) {
//创建TreeSet集合对象,通过比较器排序进行排序
TreeSet<Student> ts = new TreeSet<Student>(new Comparator<Student>() {
@Override
public int compare(Student s1, Student s2) {
// int num = (s2.getChinese()+s2.getMath())-(s1.getChinese()+s1.getMath());
//主要条件 按照总成绩的降序排序
int num = s2.getSum() - s1.getSum();
//次要条件 如果总成绩相等 就按照语文成绩进行排序 按照语文的升序进行排序
int num2 = num == 0 ? s1.getChinese() - s2.getChinese() : num;
// 如果是总成绩一样 语文成绩也一样就按照名字进行排序 ,按照自然顺序进行排序
int num3 = num2 == 0 ? s1.getName().compareTo(s2.getName()) : num2;
return num3;
}
});
//创建学生对象
Student s1 = new Student("林青霞", 98, 100);
Student s2 = new Student("张曼玉", 95, 95);
Student s3 = new Student("王祖贤", 100, 93);
Student s4 = new Student("柳岩", 100, 97);
Student s5 = new Student("风清扬", 98, 98);
Student s6 = new Student("左冷禅", 97, 99);
// Student s7 = new Student("左冷禅", 97, 99);
Student s7 = new Student("赵云", 97, 99);
//把学生对象添加到集合
ts.add(s1);
ts.add(s2);
ts.add(s3);
ts.add(s4);
ts.add(s5);
ts.add(s6);
ts.add(s7);
//遍历集合
for (Student s : ts) {
System.out.println(s.getName() + "," + s.getChinese() + "," + s.getMath() + "," + s.getSum());
}
}
}
public class Student {
private String name;
private int chinese;
private int math;
public Student() {
}
public Student(String name, int chinese, int math) {
this.name = name;
this.chinese = chinese;
this.math = math;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getChinese() {
return chinese;
}
public void setChinese(int chinese) {
this.chinese = chinese;
}
public int getMath() {
return math;
}
public void setMath(int math) {
this.math = math;
}
public int getSum() {
return this.chinese + this.math;
}
}