JAVASE高级 day_5 集合4:TreeSet

TreeSet

实现是基于TreeMap 实现的;

TreeSet中的元素是有序的。此时的有序是指的元素的顺序是字典顺序。

排序方式:

自然排序

在这里插入图片描述

定制排序

在这里插入图片描述

public static void main(String[] args) {
    //创建集合
    TreeSet  ts = new TreeSet();
    // 添加元素
    ts.add(10);
    ts.add(40);
    ts.add(30);
    ts.add(50);
    ts.add(20);
    ts.add(10);
    for (Object obj : ts){
        System.out.println(obj);
    }
}

在这里插入图片描述
Integer类实现对象的排序
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

TreeSet存储自定义对象

自然排序

自定义对象需要实现Comparable接口  此处体现的是接口的多态。
凡事存入到TreeSet集合中的对象,都需要实现排序接口。
package cn.lanqiao.demo;

import java.util.Objects;

public class Student  implements  Comparable{
    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;
        return age == student.age &&
                Objects.equals(name, student.name);
    }

    @Override
    public int hashCode() {
        return Objects.hash(name, age);
    }

    @Override
    public int compareTo(Object o) {
        // 根据年龄排序
        // 获取当前对象的年龄
        int age1 = this.getAge();
        // 获取比较对象的年龄
        Student st = (Student)o;
        int age2 = st.getAge();
        return age1 - age2;
    }

    @Override
    public String toString() {
        return "Student{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
}

测试类

System.out.println("---------------------");
TreeSet ts1 = new TreeSet();
Student st1 = new Student("张三",20);
Student st2 = new Student("李四",22);
Student st3 = new Student("王五",18);
Student st4 = new Student("赵六",21);
ts1.add(st1);
ts1.add(st2);
ts1.add(st3);
ts1.add(st4);
for (Object obj : ts1){
    System.out.println(obj);
}

按照姓名排序:

如果字符串是英文 则是按照字典顺序进行排序

如果是中文,则是按照中文的UniCode码进行排序

在排序中,如果是中文,如果第一个字相同,则按照第二个字进行排序

如果是英文,如果第一个字母相同,则按照第二个字母排序

思考练习:
优先按照年龄排序,如果年龄相同,则按照姓名排序。

@Override
    public int compareTo(Object o) {
        //优先按照年龄排序,如果年龄相同,则按照姓名排序
        Student  st =(Student) o;
        int res =  this.getAge().compareTo(st.getAge());
//        if(res == 0){
//            res = this.getName().compareTo(st.getName());
//        }
       int result =  res ==0 ? this.getName().compareTo(st.getName()):res;
        return  result;
    }

按照年龄进行降序排序

@Override
    public int compareTo(Object o) {
        //优先按照年龄排序,如果年龄相同,则按照姓名排序
        Student  st =(Student) o;
        int res =  this.getAge().compareTo(st.getAge());
//        if(res == 0){
//            res = this.getName().compareTo(st.getName());
//        }
       int result =  res ==0 ? this.getName().compareTo(st.getName()):res;
        return  -result;//将比较的结果取反
    }

结论:

用TreeSet存储自定义 对象,使用无参构造来创建集合,此时默认使用的是自然排序,对元素的排序 需要让元素的所属类实现Comparable接口,并重写compareTo方法
重写的时候,可以自定义排序规则。必须区分清楚主要条件和次要条件,同时要注意排序的要求(升序、降序)

定制排序:

在创建集合的时候 需要指定一个Compareator接口的对象

方式一:编写一个普通类,去实现接口
public class ComparatorStu  implements Comparator {
    @Override
    public int compare(Object o1, Object o2) {
        // 将对象转换为Student
        Student st1 = (Student)o1;
        Student st2 = (Student)o2;

        return st1.getAge().compareTo(st2.getAge());
    }
}

方式二:使用内部类来实现
package cn.lanqiao.demo;

import java.util.Comparator;
import java.util.TreeSet;

public class TreeSetDemo {
    public static void main(String[] args) {
        Comparator com = new ComparatorStudent();
        //创建集合
        TreeSet ts1 = new TreeSet(com);
        Student st1 = new Student("张三",20);
        Student st2 = new Student("李四",22);
        Student st3 = new Student("王五",18);
        Student st4 = new Student("张六",23);
        ts1.add(st1);
        ts1.add(st2);
        ts1.add(st3);
        ts1.add(st4);
        for (Object obj : ts1){
            System.out.println(obj);
        }

    }
    private static class  ComparatorStudent implements  Comparator{

        @Override
        public int compare(Object o1, Object o2) {
            // 将对象转换为Student
            Student st1 = (Student)o1;
            Student st2 = (Student)o2;

            return st1.getAge().compareTo(st2.getAge());
        }
    }
}
方式三:使用匿名内部类
public class TreeSetDemo {
    public static void main(String[] args) {

        //创建集合
        TreeSet ts1 = new TreeSet(new Comparator() {
            @Override
            public int compare(Object o1, Object o2) {
                // 将对象转换为Student
                Student st1 = (Student)o1;
                Student st2 = (Student)o2;

                return st1.getAge().compareTo(st2.getAge());
            }
        });
        Student st1 = new Student("张三",20);
        Student st2 = new Student("李四",22);
        Student st3 = new Student("王五",18);
        Student st4 = new Student("张六",23);
        ts1.add(st1);
        ts1.add(st2);
        ts1.add(st3);
        ts1.add(st4);
        for (Object obj : ts1){
            System.out.println(obj);
        }

    }

}
实现方式的比较★
面试题
package cn.lanqiao.demo;

import java.util.Comparator;
import java.util.HashSet;
import java.util.TreeSet;

public class TreeSetDemo {
    public static void main(String[] args) {

        HashSet set = new HashSet();
        Person p1 = new Person(1001,"AA");
        Person p2 = new Person(1002,"BB");
        set.add(p1);//p1 在集合中的存储位置是由1001 和AA计算所得
        set.add(p2);
        System.out.println(set);
        p1.setName("CC");//将AA 改为了CC
        System.out.println(set);
        boolean b = set.remove(p1);//此时会根据p1的hash值来计算需要移除的元素所在的位置
        System.out.println(b);//false'
        System.out.println(set);//
        set.add(new Person(1001,"CC"));//存储的位置是由1001和CC计算所得  
        System.out.println(set);//
        set.add(new Person(1001,"AA"));//虽然计算得到的位置和第二个对象相同,但是hash值不同且equals返回false
        
        System.out.println(set);//

    }

}

在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值