java集合框架:Set集合

特点:

- 1 不能存储重复数据
- 2 没有索引,不能使用普通的for循环。 增强for和迭代器都可以
- 3 存取顺序不一致

treeset 自然排序

        TreeSet<Integer> set = new TreeSet<>();
        set.add(50);
        set.add(30);
        set.add(70);
        set.add(60);
        set.add(20);
        set.add(100);
        System.out.println(set);
结果:
[20, 30, 50, 60, 70, 100]

treeset 自然排序 (对象)

添加学生对象 报错  原因是学生类 没有实现Comparable接口

解决错误 (自然排序)

给学生实现Comparable接口

- 因为后面要比较的是学生对象,索引接口那里添加具体的泛型的类型为Student
- 这里重写的compareTo方法里,是按年龄排序,后续再解释原理
- -  compareTo方法如果返回的是正数 新的数据会排到右侧
- -  compareTo方法如果返回的是负数 新的数据会排到左侧
- -  compareTo方法如果返回的是0 新的数据就不会被添加

返回正数,表明当前存入的值比老值大,应该排在右边

.......

再次运行

需求 先按你年龄排序 如果年龄相等 按姓名排序

    @Override
    public int compareTo(Student o) {
        int result = this.age - o.age;

        //按照年龄从小到大排序 如果年龄相等 按照名字排序
        return result == 0 ? this.name.compareTo(o.name) : result;

        //return this.age - o.age;
        //return o.age - this.age;
    }

Comparator比较器方式排序

- 案例需求
- - - 两个集合,各存3个学生
- - - 一个集合按照年龄从小到大排序,另外一个按照年龄从大到小排序
- 实现步骤
- - - 创建TreeSet集合对象时利用构造方法传入比较器对象。
- - - 比较器对象以匿名内部类或者lambda表达式的形式传入,重写compare(T o1,T o2)方法,集合就会按照compare方法的规则排序
- - - 重写方法时,一定要注意排序规则必须按照要求的主要条件和次要条件来写

Student类代码

public  class Student implements Comparable<Student>{
    String name;
    int age;
...........................................
    @Override
    public String toString() {
        return "{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
      
      @Override
      public int compareTo(Student o) {
          return 0;
      }
}

 测试类代码:

  • 创建了两个集合set1和set2,分别用匿名内部类和lambda的方式传入的比较器对象

  • 注意set2中的lambda方式,由于存在泛型,所以添加 (Comparator<Student>)

   public static void main(String[] args) {
        //按照年龄从小到大排
        TreeSet<Student> ts01 = new TreeSet<>(new Comparator<Student>() {
            @Override
            public int compare(Student o1, Student o2) {
                return o1.age - o2.age;
            }
        });
        ts01.add(new Student("zs", 24));
        ts01.add(new Student("xiaom", 30));
        ts01.add(new Student("lisi", 19));
        ts01.add(new Student("daming", 50));
        ts01.add(new Student("wangwu", 25));
        ts01.add(new Student("hehe", 30));
        ts01.add(new Student("daming", 50));
        System.out.println(ts01);

        //按照年龄从大到小排
        TreeSet<Student> ts02 = new TreeSet<>(new Comparator<Student>() {
            @Override
            public int compare(Student o1, Student o2) {
                return o2.age - o1.age;
            }
        });
        ts02.add(new Student("zs", 24));
        ts02.add(new Student("xiaom", 30));
        ts02.add(new Student("lisi", 19));
        ts02.add(new Student("daming", 50));
        ts02.add(new Student("wangwu", 25));
        ts02.add(new Student("hehe", 30));
        ts02.add(new Student("daming", 50));
        System.out.println(ts02);
    }

lambda实现

 

//按照年龄从小到大排
TreeSet<Student> ts01 = new TreeSet<>((o1, o2) -> o1.age - o2.age);

ts01.add(new Student("zs", 24));
ts01.add(new Student("xiaom", 30));
ts01.add(new Student("lisi", 19));
ts01.add(new Student("daming", 50));
ts01.add(new Student("wangwu", 25));
ts01.add(new Student("hehe", 30));
ts01.add(new Student("daming", 50));
System.out.println(ts01);

//按照年龄从大到小排
TreeSet<Student> ts02 = new TreeSet<>((o1, o2) -> o2.age - o1.age);

ts02.add(new Student("zs", 24));
ts02.add(new Student("xiaom", 30));
ts02.add(new Student("lisi", 19));
ts02.add(new Student("daming", 50));
ts02.add(new Student("wangwu", 25));
ts02.add(new Student("hehe", 30));
ts02.add(new Student("daming", 50));
System.out.println(ts02);

两种比较方式总结

  • 两种比较方式小结

    • 自然排序: 需要比较的对象的类要实现Comparable接口,重写compareTo方法,根据返回值进行排序

    • 比较器排序: 创建TreeSet对象的时候传递Comparator的实现类对象,重写compare方法,根据返回值进行排序

    • 在使用的时候,默认使用自然排序,当自然排序不满足现在的需求时,必须使用比较器排序

  • 两种方式中关于返回值的规则

    • 如果返回值为负数,表示当前存入的元素是较小值,存左边

    • 如果返回值为0,表示当前存入的元素跟集合中元素重复了,不存

    • 如果返回值为正数,表示当前存入的元素是较大值,存右边

阅读剩余
THE END