TreeSet

TreeSet集合存储元素特点:
    1 无序不可重复,但是储存的元素可以按照大小顺序排序!称为可排序集合。
    
    2 无序:这里的无序指的是存进去的顺序和取出来的顺序不同。并且没有下标。
 
1 TreeSet集合底层实际上是一个TreeMap
2 TreeMap集合底层是一个二叉树
3 放到TreeSet中的元素,等同于放到TreeMap集合key部分了。
4 TreeSet集合中的元素:无序,不可重复,但是可以按照元素的大小顺序自动排序。
称为:可排序集合。
 
 
 
对自定义的类型来说,TreeSet可以排序吗?
    以下程序中对于Person来说,无法排序。因为没有指定Person对象之间的比较规则。
    谁大谁小没有说明啊。
    
    以下程序运行的时候出现了这个异常:
         java.lang.ClassCastException
            class com.javaSe.HashSet.Person cannot be cast to class java.lang.Comparable
            
    出现这个异常的原因是:
        Person类没有实现java.lang.Comparable接口。
 
 
TreeSet集合中元素可排序的第二种方式:使用比较器的方式
最终的结论:
    方法TreeSet或者TreeMap集合key部分的元素要想做到排序,包括两种方式:
        第一种:放在集合中的元素实现java.lang.Comparable接口
        第二种:在构造TreeSet或者TreeMap集合的时候给他传一个比较器对象。Comparator
        
Comparator 和 Comparable 怎么选择呢?
    当比较规则不会发生改变的时候,或者说当比较规则只有一个的时候,建议实现Comparable接口。
    如果比较规则有多个,并且需要多个比较规则之间频繁切换,建议使用Comparator接口。
    
    Comparator接口的设计符合OCP原则。
 
 
 
案例1:
package com.javaSe.HashSet;


import java.util.Set;
import java.util.TreeSet;


/*
TreeSet集合存储元素特点:
    1 无序不可重复,但是储存的元素可以按照大小顺序排序!称为可排序集合。
    
    2 无序:这里的无序指的是存进去的顺序和取出来的顺序不同。并且没有下标。
*/
public class TreeSetTest01 {
    public static void main(String[] args) {
        // 创建TreeSet集合
        Set<String> strs = new TreeSet<>();
        // 添加元素
        strs.add("567");
        strs.add("678");
        strs.add("789");
        strs.add("123");
        strs.add("234");
        strs.add("456");
        strs.add("567");
        strs.add("678");
        strs.add("789");
        strs.add("123");
        strs.add("234");
        strs.add("456");
        
        // 遍历
        for (String s : strs){
            System.out.println(s);
        }
    }
}

 

 

案例2:

package com.javaSe.HashSet;


import java.util.TreeSet;


/*
1 TreeSet集合底层实际上是一个TreeMap
2 TreeMap集合底层是一个二叉树
3 放到TreeSet中的元素,等同于放到TreeMap集合key部分了。
4 TreeSet集合中的元素:无序,不可重复,但是可以按照元素的大小顺序自动排序。
称为:可排序集合。


*/
public class TreeSetTest02 {
    public static void main(String[] args) {
        // 创建一个TreeSet集合
        TreeSet<String> ts = new TreeSet<>();
        // 添加String
        ts.add("zhangsan");
        ts.add("list");
        ts.add("wangwu");
        ts.add("liuliu");
        ts.add("zhaoqi");
        
        // 遍历
        for (String s : ts){
            // 按照字段顺序,升序排列
            System.out.println(s);
        }
    
        TreeSet<Integer> ts1 = new TreeSet<>();
        ts1.add(123);
        ts1.add(44);
        ts1.add(22);
        ts1.add(11);
        ts1.add(45);
        ts1.add(88);
        
        for (Integer i : ts1){
            // 升序
            System.out.println(i);
        }
        
    }
}


/*
数据库中有很多数据:
    userid      name        birth
    -----------------------------------
    1           zs          2019-01-11
    2           ls          2019-02-11
    3           ww          2019-03-11
    4           ll          2019-04-11
    
    编写程序从数据库当中取出数据,在页面展示用户信息的时候按照生日升序或者降序
    这个时候可以使用TreeSet集合,因为TreeSet集合放进去,拿出来就是有顺序的。
*/

 

 

案例3:

package com.javaSe.HashSet;


import java.util.TreeSet;


/*
对自定义的类型来说,TreeSet可以排序吗?
    以下程序中对于Person来说,无法排序。因为没有指定Person对象之间的比较规则。
    谁大谁小没有说明啊。
    
    以下程序运行的时候出现了这个异常:
         java.lang.ClassCastException
            class com.javaSe.HashSet.Person cannot be cast to class java.lang.Comparable
            
    出现这个异常的原因是:
        Person类没有实现java.lang.Comparable接口。
*/
public class TreeSetTest03 {
    public static void main(String[] args) {
        Person p1 = new Person(22);
        Person p2 = new Person(11);
        Person p3 = new Person(44);
        Person p4 = new Person(10);
        
        // 创建TreeSet集合
        TreeSet<Person> person = new TreeSet<>();
        // 添加元素
        person.add(p1);
        person.add(p2);
        person.add(p3);
        person.add(p4);
        
        for (Person s : person){
            System.out.println("Person[age=" + s + "]");
        }
        
    }
}


class Person{
    int age;
    
    public Person() {
    }
    
    public Person(int age) {
        this.age = age;
    }
    
    @Override
    public String toString() {
        return "Person{" +
                "age=" + age +
                '}';
    }
}

 

 

案例4:

package com.javaSe.HashSet;


import java.util.TreeSet;


public class TreeSetTest04 {
    public static void main(String[] args) {
        Customer p1 = new Customer(22);
        Customer p2 = new Customer(11);
        Customer p3 = new Customer(44);
        Customer p4 = new Customer(10);
        
        // 创建TreeSet集合
        TreeSet<Customer> customer = new TreeSet<>();
        // 添加元素
        customer.add(p1);
        customer.add(p2);
        customer.add(p3);
        customer.add(p4);
        
        for (Customer s : customer){
            System.out.println(s);
        }
        
    }
}


// 需要在TreeSet集合中的元素需要时间java.lang.Comparable接口。
// 并且实现compareTo方法。equals可以不写。
class Customer implements Comparable<Customer>{
    int age;
    
    public Customer() {
    }
    
    public Customer(int age) {
        this.age = age;
    }
    
    // 需要在这个方法中编写比较的逻辑,或者说比较的规则,按照什么进行比较!
    // k.compareTo(t.key)
    // 拿着参数k和集合中的每一个k进行比较,返回值可能是>0 <0 =0 都有可能
    // 比较规则最终还是由程序员指定的,按照年龄升序。或者按照年龄降序。
    public int compareTo(Customer o) {// c1.compareTo(c2);
        // this是c1
        // c是c2
        // c1 和 c2比较的时候,就是this和c比较
        int age1 = this.age;
        int age2 = o.age;
        
        // 菜鸟的写法
        /*if(age1 == age2){
            return 0;
        } else if(age1 > age2) {
            return 1;
        } else {
            return -1;
        }*/
        
        return o.age - this.age; // = 0 >0 <0
    }
    
    public String toString() {
        return "Customer[" + "age=" + age + "]";
    }
}

 

 

案例5:

package com.javaSe.HashSet;


import java.util.TreeSet;


/*
先按照年龄升序,如果年龄一样的,再按照姓名升序
*/
public class TreeSetTest05 {
    public static void main(String[] args) {
        TreeSet<Vip> vips = new TreeSet<>();
        vips.add(new Vip("张三",20));
        vips.add(new Vip("李四",10));
        vips.add(new Vip("王五",30));
        vips.add(new Vip("刘六",6));
        
        for(Vip v : vips){
            System.out.println(v);
        }
    }
}


class Vip implements Comparable<Vip>{
    String name;
    int age;
    
    
    public Vip(String name, int age) {
        this.name = name;
        this.age = age;
        
    }
    
    @Override
    public String toString() {
        return "Vip{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
    
    /*
    compareTo方法的返回值很重要:
        返回0表示相同,Value会覆盖
        返回>0,会继续在右子树上找。【10 - 9 = 1,1 > 0的说明左边的数字比较大。所以在右边找。】
        返回<0,会继续在左子树上找。
     */
    public int compareTo(Vip v) {
        // 写排序规则,按照什么进行比较。
        if(this.age == v.age){
            // 年龄相同时,按照姓名排序
            // 姓名是String类型,可以直接比,调用compareTo来完成比较
            return this.name.compareTo(v.name);
        } else {
            // 年龄不一样
            return this.age - v.age;
        }
    }
}

 

 

案例6:

package com.javaSe.TreeSet;


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


/*
TreeSet集合中元素可排序的第二种方式:使用比较器的方式
最终的结论:
    方法TreeSet或者TreeMap集合key部分的元素要想做到排序,包括两种方式:
        第一种:放在集合中的元素实现java.lang.Comparable接口
        第二种:在构造TreeSet或者TreeMap集合的时候给他传一个比较器对象。Comparator
        
Comparator 和 Comparable 怎么选择呢?
    当比较规则不会发生改变的时候,或者说当比较规则只有一个的时候,建议实现Comparable接口。
    如果比较规则有多个,并且需要多个比较规则之间频繁切换,建议使用Comparator接口。
    
    Comparator接口的设计符合OCP原则。
*/
public class TreeSetTest06 {
    public static void main(String[] args) {
        // 创建TreeSet集合的时候,需要使用这个比较器。
        // TreeSet<WuGui> wuGuis = new TreeSet<>();// 这样不行,没有通过构造方法传递一个比较器进去。
        
        // 给构造方法传递一个比较器。
        // TreeSet<WuGui> wuGuis = new TreeSet<>(new WuGuiiComparator());
        
        // 大家可以使用匿名内部类的方式(这个类没有名字,直接new接口。)
        TreeSet<WuGui> wuGuis = new TreeSet<>(new Comparator<WuGui>() {
            public int compare(WuGui o1, WuGui o2) {
                return o1.age - o2.age;
            }
        });
        
        wuGuis.add(new WuGui(1000));
        wuGuis.add(new WuGui(800));
        wuGuis.add(new WuGui(900));
        wuGuis.add(new WuGui(666));
        
        for(WuGui wgs : wuGuis){
            System.out.println(wgs);
        }
    }
}


// 乌龟
class WuGui{
    int age;
    
    public WuGui(int age){
        this.age = age;
    }


    public String toString() {
        return "小乌龟[" +
                "age=" + age +
                ']';
    }
}


// 单独在这里编写一个比较器
// 比较器实现java.util.Comparator接口。(Comparable是java.lang包下的。Comparator是java.util包下的。)
/*
class WuGuiiComparator implements Comparator<WuGui> {
    
    public int compare(WuGui o1, WuGui o2) {
        // 指定比较规则
        // 按照年龄排序
        return o1.age - o2.age;
    }
}*/

 

posted @ 2020-08-06 22:12  xlwu丶lz  阅读(229)  评论(0编辑  收藏  举报