1. Set集合
Set集合是Collection单列集合的子接口,主要特点:
- Set集合可以去除重复元素
- Set集合的存入顺序和取出顺序不一致
- Set集合没有索引,不能使用普通for循环遍历
Set集合遍历:
public class Demo {
public static void main(String[] args) {
Set<String> set = new TreeSet<>();
set.add("aaa");
set.add("ddd");
set.add("bbb");
set.add("aaa");
//迭代器遍历
Iterator<String> it = set.iterator();
while (it.hasNext()){
String s = it.next();
System.out.println(s);
}
System.out.println("*****************************");
//增强for循环
for (String s : set) {
System.out.println(s);
}
}
}
2. TreeSet集合
TreeSet集合是Set接口的实现类,主要特点:
- TreeSet集合的底层数据结构是红黑树
- 不可以存储重复元素
- 没有索引,不能使用普通for循环
- 可以将元素按照规则进行排序(自然排序和比较器排序)
2.1 自然排序Comparable
- 使用TreeSet集合存储学生对象并遍历,创建TreeSet集合使用无参构造方法
- 要求:按照年龄从小到大排序,年龄相同时,按照姓名的字母顺序排序
实现步骤:
- 使用空参构造创建TreeSet集合
- 自定义的Student类实现Comparable接口
- 重写接口中的compareTo方法
public class Student implements Comparable<Student>{
private String name;
private int age;
@Override
public int compareTo(Student o) {
//主要判断条件
int result = this.age - o.age;
//次要判断条件
result = this.age == o.age ? this.name.compareTo(o.name) : result;
return result;
}
@Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
", 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;
}
public Student(String name, int age) {
this.name = name;
this.age = age;
}
public Student() {
}
}
import java.util.TreeSet;
public class TreeSetDemo {
public static void main(String[] args) {
TreeSet<Student> students = new TreeSet<>();
Student stu1 = new Student("zhangliang", 59);
Student stu2 = new Student("likui", 43);
Student stu3 = new Student("abc", 38);
Student stu4 = new Student("acb", 38);
Student stu5 = new Student("zhouyu", 26);
students.add(stu1);
students.add(stu2);
students.add(stu3);
students.add(stu4);
students.add(stu5);
System.out.println(students);
}
}
2.2 比较器排序Comparator
TreeSet集合的构造方法接收Comparator的实现类对象(匿名内部类),重写compare方法
案例需求:
- 使用TreeSet集合存储老师对象并遍历,创建TreeSet集合使用带参构造方法
- 要求:按照年龄从小到大排序,年龄相同时,按照姓名的字母顺序排序
public class Teacher {
private String name;
private int age;
@Override
public String toString() {
return "Teacher{" +
"name='" + name + '\'' +
", 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;
}
public Teacher(String name, int age) {
this.name = name;
this.age = age;
}
public Teacher() {
}
}
import java.util.Comparator;
import java.util.TreeSet;
public class TreeSetDemo1 {
public static void main(String[] args) {
//使用匿名内部类创建Comparator实现类,重写compare方法
TreeSet<Teacher> teachers= new TreeSet<>(new Comparator<Teacher>() {
@Override
public int compare(Teacher o1, Teacher o2) {
int result = o1.getAge() - o2.getAge();
result = result == 0 ? o1.getName().compareTo(o2.getName()) : result;
return result;
}
});
Teacher teacher1 = new Teacher("abc" , 26);
Teacher teacher2 = new Teacher("acb" , 26);
Teacher teacher3 = new Teacher("wangling" , 19);
Teacher teacher4 = new Teacher("deshrng" , 56);
Teacher teacher5 = new Teacher("hangjinh" , 36);
teachers.add(teacher1);
teachers.add(teacher2);
teachers.add(teacher3);
teachers.add(teacher4);
teachers.add(teacher5);
System.out.println(teachers);
}
}
2.3 自然排序和比较器排序比较
- 自然排序: 自定义类实现Comparable接口,重写compareTo方法,根据返回值进行排序
- 比较器排序: 创建TreeSet对象的时候传递Comparator的实现类对象,重写compare方法,根据返回值进行排序
- 在使用TreeSet集合的时候,首先考虑自然排序,当自然排序不满足所需要求时,则使用比较器排序
两种方式中关于返回值的规则:
- 如果返回值为负数,表示当前存入的元素是较小值,存左边
- 如果返回值为0,表示当前存入的元素跟集合中元素重复了,不存
- 如果返回值为正数,表示当前存入的元素是较大值,存右边
3. HashSet集合
HashSet集合是Set接口的实现类,主要特点:
- HashSet集合底层数据结构是哈希表
- 数据的存取顺序无序
- 不可以存储重复元素
- 没有索引,不能使用普通for循环遍历
3.1 哈希表
哈希值:
- 哈希值是根据对象的地址或者字符串或者数字算出来的int类型的数值
- hashCode()是获取对象哈希值的方法,如果不重写hashCode()方法,默认使用对象地址值计算哈希值
- 重写hashCode()方法后,不同属性值的对象可能会得到相同的哈希值
3.2 HashSet集合存储学生对象并遍历
学生类,重写hashCode和equals方法,去除重复学生对象:
public class Student {
private String name;
private int 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;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Student student = (Student) o;
if (age != student.age) return false;
return name != null ? name.equals(student.name) : student.name == null;
}
@Override
public int hashCode() {
int result = name != null ? name.hashCode() : 0;
result = 31 * result + age;
return result;
}
}
测试类,将学生对象存入HashSet集合并遍历:
public class HashSetDemo02 {
public static void main(String[] args) {
//创建HashSet集合对象
HashSet<Student> hs = new HashSet<Student>();
//创建学生对象
Student s1 = new Student("林青霞", 30);
Student s2 = new Student("张曼玉", 35);
Student s3 = new Student("王祖贤", 33);
Student s4 = new Student("王祖贤", 33);
//把学生添加到集合
hs.add(s1);
hs.add(s2);
hs.add(s3);
hs.add(s4);
//遍历集合(增强for)
for (Student s : hs) {
System.out.println(s.getName() + "," + s.getAge());
}
}
}
如有错误欢迎留言评论,及时更正。2021年六月四日 羽露风