黑马程序员_009_TreeSet的两种排序方式和HashSet保持元素唯一性的方式

本文详细介绍了HashSet如何通过元素的hashCode()和equals()方法保证元素的唯一性,并演示了TreeSet的两种排序方式:自然排序与自定义排序器。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

-------  android培训java培训、期待与您交流! ----------
1、HashSet保持元素唯一性的方式
HashSet是如何保证元素的唯一性?是通过元素的两个方法,hashCode()和equals()来完成。如果元素的HashCode值相同,才会判断equals是否为true,如果元素的哈希值不同,不会调用equals。另外:若两个元素的值不同,地址值相同,过程是这样的:先比较地址值,发现相同,然后比较equals,发现值不同,则,在哈希表中,该地址值下回存入两个不同的对象,即一个地址两个对象,在打印时,可打印出这两个对象。

HashSet数据结构式哈希表,线程是非同步的。保证元素唯一性的原理,判断元素的hashCode是否相同,如果相同,还会继续判断元素的equals方法,是否为true

注意:对于判断元素是否存在以及删除等操作,都依赖于元素的hashcode和equals方法
class Demo
{
        /*
        public int hashCode()
        {
                return 60;//返回值3c, 十六进制形式
        }
        */
}
class HashSetDemo
{
        public static void sop(Object obj)
        {
                System.out.println(obj);
        }
        public static void main(String[] args)
        {
                Demo d = new Demo();
                Demo d1 = new Demo();
                sop(d);//因为重写了hashCode(),所以打印的d和d1的地址值是一样的
                sop(d1);//这是因为,d.toString()时,调用hashCode(),返回d的哈希值
                            //但是我们重写后,返回的是3c,因此d  和d1打印地址值相同

                HashSet  hs = new HashSet();
                hs.add("java01");
                hs.add("java02");
                hs.add("java03");
                hs.add("java04");
                hs.add("java03");
                hs.add("java04");

                sop(hs.add("java"));//add方法返回值为boolean的,此时打印true,能存
                sop(hs.add("java"));//应为hs中已经存在java,不能继续存入,打印false
                Iterator it = hs.iterator();
                while(it.hasNext())//打印后只1234,因为HashSet中元素不重复
                        sop(it.next())
        }
}
2、TreeSet的两种排序方式
排序的第一种方式:让元素自身具备比较性,元素实现compareable接口,覆盖compareTo()方法。这种方式也称为元素的自然顺序,或默认顺序。

        
class TreeSetDemo
{
        public static void main(String[] args)
        {
                TreeSet ts = new TreeSet();    
                ts.add("fd");
                ts.add("cdf");
                ts.add("Dd");
                ts.add("b");
                Iterator it = ts.iterator();
                while(it.hasNext())
                {
                        System.out.println(it.next());
                        //结果:     Dd     b         cdf       fd 
                        //按首字母值排序,升序
                }


        }
}

/*
向TreeSet中存储自定义对象:重写compareTo方法,按我们自定义的方式返回值,先比较主要元素,若主要元素相同就比较次要元素。
*/
class TreeSetDemo
{
        public static void main(String[] args)
        {
                TreeSet ts = new TreeSet();    
                ts.add(new Student("zhangsan",19);
                ts.add(new Student("lisi",30);
                ts.add(new Student("wangwu",19);
                ts.add(new Student("zhangsan",13);

                Iterator it = ts.iterator();
                while(it.hasNext())
                {
                        System.out.println(it.next());
                     
                }
        }
}
class Student implements Comparable
{
        private String name;
        private int age;
        Student(String name,int age)
        {
                this.name = name;
                this.age = age;
        }
        public int compareTo(Object obj)
        {
                /*此时按升序排列
                if(!(obj instanceof Student))
                        throw new RunTimeException("不是学生");
                Student s = (Student)obj;
                if(this.age>s.age)
                        return 1;
                if(this.age==s.age)
                         return (this.name).compareTo(s.name);//String类本身就实现了Compareable接口,有compareTo方法
                return -1;*/

                //如果这样,那么元素是按存入的顺序排列的,存入元素时,会自动调用compareTo,返回1表示大于,返回0表示等于(此时不存入),返回-1表示小于。在这里全返回1表示后存入的对象比前一个对象大。
                return  1;
        }
        public String getName()
        {
                return name;
        }
        public int getAge()
        {
                retrun age;
        }
}


排序的第二种方式:当元素自身不具备比较性,或具备的比较性不是所需要的。这时需要让集合自身具备比较性。在集合一初始化时,就有了比较方式。定义了比较器,将比较器对象作为参数传递给TreeSet集合的构造函数

当两种排序都存在时,以比较器为主


class Student implements Comparable
{
        private String name;
        private int age;
        Student(String name,int age)
        {
                this.name = name;
                this.age = age;
        }
        public int compareTo(Object obj)
        {
               此时按升序排列
                if(!(obj instanceof Student))
                        throw new RunTimeException("不是学生");
                Student s = (Student)obj;
                if(this.age>s.age)
                        return 1;
                if(this.age==s.age)
                         return (this.name).compareTo(s.name);//String类本身就实现了Compareable接口,有compareTo方法
                return -1;

              
        }
        public String getName()
        {
                return name;
        }
        public int getAge()
        {
                retrun age;
        }
}
class TreeSetDemo
{
        public static void main(String[] args)
        {
                TreeSet ts = new TreeSet (new MyCompare());     //表示使用指定比较器
                ts.add(new Student("zhangsan",19);
                ts.add(new Student("lisi",30);
                ts.add(new Student("wangwu",19);
                ts.add(new Student("zhangsan",13);

                Iterator it = ts.iterator();
                while(it.hasNext())
                {
                        System.out.println(it.next());
                        //结果:     Dd     b         cdf       fd 
                        //按首字母值排序,升序
                }
        }
}
定义一个类,实现Comparator接口,覆盖compare方法。
class MyCompare implements Comparator//自定义比较器
{
        public int compare(Object c1,Object c2)
        {
                Student s1 = (Student)o1;
                Student s2 = (Student)o2;
                int  num = s1.getName().compareTo(s2.getName());
                if(num==0)//当name相同时,比较age
                {
                        return new Integer(s1.getAge()).compareTo(new Integer(s2.getAge());
                }
                return num;
        }
}

比较器调用过程: 就是让集合具备比较的功能,使用集合构造函数方法
创建TreeSet集合对象,此时:
         TreeSet ts = new TreeSet(new MyCompare()); 表示使用自定义比较器
       
创建类实现接口Comparator,覆盖接口的compare方法
        class MyCompare implements Comparator//自定义比较器
        {
        public int compare(Object c1,Object c2)
        {
自定义比较的方式,最后的返回值
return 正数或负数或0;一般就是1  -1  0
}
}
向TreeSet对象中添加元素,此时元素就自动的,按自定义的比较器在集合内排序存放

compareTo调用过程理解: 让集合元素具备比较性
创建TreeSet集合对象,此时:
           TreeSet ts = new TreeSet(); 表示使用compareTo()方法
创建类实现Comparable接口,覆盖compare方法。并且此类生成的对象,是准备向集合中添加的元素。 在覆盖后的compare方法中对该类的成员如name  age等进行比较,返回值1 -1 或0
向集合中添加元素,集合就会自动调用compare方法,按覆盖后的compare方法进行排序存放
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值