day20 比较器、set、map、散列

1. Set 和排序
    1.1 概述
        set 特点: 无序、不可重复、添加顺序和取出顺序不一定一致。
        Set --> SortedSet --> TreeSet :底层是红黑树,要添加的元素必须按照某个规则进行排序。
2 TreeSet
    2.1 概述
        set 特点: 无序、不可重复、添加顺序和取出顺序不一定一致。
        Set --> SortedSet --> TreeSet :底层是红黑树,要添加的元素必须按照某个规则进行排序。
        数字: 默认升序。    字符串:默认比较每一位的ASCII码值。    时间:默认自然日期(昨天,今天,明天)。
    2.2使用
        import java.text.ParseException;
        import java.text.SimpleDateFormat;
        import java.util.Date;
        import java.util.TreeSet;

        public class Test{
            public static void main(String []args) throws ParseException{
                //TreeSet对象创建
                TreeSet trs = new TreeSet();
                //添加数据
                trs.add(1);
                trs.add(5);
                trs.add(4);
                trs.add(2);
                System.out.println(trs);    //1 2 4 5
                trs = new TreeSet();
                trs.add("1");
                trs.add("15");
                trs.add("2");
                trs.add("5");
                System.out.println(trs);    // 1 15 2 5
                String strTime1 = "2021-12-02";
                String strTime2 = "2020-01-22";
                String strTime3 = "2024-06-12";
                SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
                Date d1 = sdf.parse(strTime1);
                Date d2 = sdf.parse(strTime2);
                Date d3 = sdf.parse(strTime3);
                trs = new TreeSet();
                trs.add(d1);
                trs.add(d2);
                trs.add(d3);
                System.out.println(trs);
            }
        }
    2.3 为什么会排序? 其他类型可不可以?
        为什么 String Integer Date 能排序, 其他的类型不行?
            因为以上三种类型都实现了 Comparable 接口,并实现了  compareTo() 方法。
            而往 TreeSet 中添加数据的时候,会自动调用该对象的 compareTo() 方法,因此它们可以排序。
            但是如果我们想添加其他元素,尤其是自定义类型的时候,就不行了,需要我们自己实现 Comparable 接口, 实现compareTo() 方法。
    import java.util.TreeSet;
    public class Test{
        public static void main(String[]args){
            //创建TreeSet对象
            TreeSet ts = new TreeSet();
            //添加User类型数据
            ts.add(new User (15));
            ts.add(new User (22));
            ts.add(new User (33));
            System.out.println(ts);
            
        }
    }
    class User implements Comparable{
        int age;
        
        @Override
        public String toString() {
            return "User [age=" + age + "]";
        }

        public User(int age) {
            super();
            this.age = age;
        }

        @Override
        public int compareTo(Object o){
                    // this 是要要添加的元素 , o 是集合中的每一个元素
                    // 返回值为0 , 说明相等, 就不添加
                    // 返回小于0 的, 说明要添加的元素比集合中的元素小,就放到前面
                    // 返回大于0的,说明要添加的元素比集合中的元素大,就放到后面
            if(o instanceof User){
                User user = (User) o;
                //升序
                return this.age - user.age;
                /*降序
                 return user.age - this.age.
                 */
            }
            return -1;
        }
    }
3. 树
    3.1 二叉查找树
        类似于二分法查找,查询效率较高。
        左叶子,永远都比根节点小。
        右叶子,永远都比根节点大。
    这种方式是二分查找的思想,查询所需要的最大次数,等同于二叉树的高度。
        在添加数据的时候,也是类似的方式,一层层找一直找到适合的节点的位置。
    缺点:
        如果一直添加比根节点小,或者比根节点大的数据,这样会导致查询变慢。
    3.2 红黑树
        红黑树是一种自平衡的二叉查找树。
            为了解决二叉树多次插入新节点而导致的不平衡,红黑树就诞生了。
            完全符合二叉查找的特性:
            1.节点是红色或者黑色。
            2.根节点一定是黑色。
            3.每个子节点都是黑色的空节点。
            4.每个红节点的两个字节点都是黑色。
            5.从任何节点到其每一个子节点都有相同数量的黑色节点。
4. 排序
    4.1 概述
        比较器类有两种:
            1. java.lang.Comparable 接口, 并实现 compareTo()方法
            2. java.util.Comparator 比较器类
    4.2 Comparable    
        如果我们的自定义类型想要放到treeSet中,必须实现Comparable接口,否则就无法使用treeSet进行数据保存。
    4.3 Comparator
        4.3.1 概述
            比如我们现在要保存数字,并且要求降序。
            而 Integer 中,默认为升序,没法改变源码,可以使用 Comparator 解决该问题。 Comparator 的优先级 要大于 Comparable 。
        4.3.2 使用
            保村数字,并降序。
        import java.util.Comparator;
        import java.util.TreeSet;

        public class Test{
            @SuppressWarnings({ "unchecked", "rawtypes" })
            public static void main(String[] args){
                //创建一个TreeSet对象
                
                TreeSet ts = new TreeSet( new Comparator() {
                    @Override
                    public int compare(Object o1, Object o2) {
                        // o1是要添加的元素,o2是集合中的元素
                        Integer i1 = (Integer) o1;
                        Integer i2 = (Integer) o2;
                        // i1-i2是升序, i2-i1是降序
                        return i2 - i1;
                    }
                } );
                
                //添加数据
                ts.add(15);
                ts.add(21);
                ts.add(6);
                ts.add(33);
                System.out.println(ts);    //6 11 19 28
                
            }
        }

    
5.Collections
    list 想要排序,元素必须实现 Comparable 接口。
    如果元素自身没有实现 Comparable 接口,是不能调用 sort 方法的,会报错。
    如果没有实现接口, 就可以使用 Comparator 方法,sort 方法可以进行重载,来接受 Comparator
    import java.util.ArrayList;
    import java.util.Collections;
    import java.util.Comparator;

    public class Test{
        public static void main(String[]args){
            //创建一个ArrayList对象
            ArrayList al = new ArrayList();
            //添加数据
            al.add(5);
            al.add(4);
            al.add(8);
            al.add(2);
            Collections.sort(al, new Comparator() {

                @Override
                public int compare(Object o1, Object o2) {
                    Integer i1 = (Integer) o1;
                    Integer i2 = (Integer) o2;
                    return i2 - i1;
                }
            });
            System.out.println(al);    // 8 5 4 2
        }
    }
6. 总结
    自己添加元素时,可以实现 Comparable 接口。
    如果后期需要重新排序,可以调用 Comparator 方法排序。
    因为 Comparator 和 Comparable 同时存在的时候,Comparator 优先级要高。
7.HashSet
    7.1 散列表
        散列表,也叫哈希表。是根据关键码值直接访问的数据结构。 HashSet 的底层就是 HashMap 的 Key 部分,屏蔽了 HashMap 的 value 值。
    1.调用 Key 的 hashCode 方法生成 hash 值。
    2.散列存储方式。
    3.生成数组索引。
    4.判断数组对应的索引中是否有节点
    5.没有节点直接添加
    6.有节点,判断是否存在当前元素
    7.如果链表中的节点个数大于等于8就转为树。
    import java.util.HashSet;

    public class Test05{
        public static void main(String[]args){
            //创建散列表对象
            HashSet hs  = new HashSet();
            hs.add("a");
            hs.add("c");
            hs.add("e");
            hs.add("g");
            hs.add("j");
            System.out.println(hs);
            for(Object obj:hs){
                System.out.println(obj);
            }
        }
    }

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值