精华内容
下载资源
问答
  • 自然排序:如果一个类的元素要想要能够进行自然排序, 就必须实现自然排序接口实现Comparable接口重写CompareTo()方法 该学生类进行自然排序,实现Comparable接口 package day17_Set_son_4; /* * 如果一个类的元素...

    自然排序:如果一个类的元素要想要能够进行自然排序,
    就必须实现自然排序接口实现Comparable接口重写CompareTo()方法

    该学生类进行自然排序,实现Comparable接口

    package day17_Set_son_4;
    /*
     * 如果一个类的元素要想要能够进行自然排序,就必须实现自然排序接口
     */
    public class Student implements Comparable<Student>{
    	private String name;
    	private int age;
    	
    	public Student(String name, int age) {
    		super();
    		this.name = name;
    		this.age = age;
    	}
    	
    	public Student() {
    		super();
    		// TODO Auto-generated constructor stub
    	}
    	
    	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 int compareTo(Student s) {
    		//这里返回说明,其实是根据我的排序规则来排序的
    		//按照年龄大小,主要条件
    		int num = this.age - s.age;
    		//次要条件,年龄相同的时候还得看姓名是否相同
    		//如果年龄和姓名一致,才是同一个元素
    		int num2 = num == 0 ? this.name.compareTo(s.name) : num;
    		return num2;
    	}
    }
    
    

    下列集合添加Student对象,并对学生类对象进行自然排序

    public class TreeSetDemo2 {
    	public static void main(String[] args) {
    		//创建集合对象
    		TreeSet<Student> ts = new TreeSet<Student>();
    		
    		//创建学生对象
    		Student s1 = new Student("luzhen", 22);
    		Student s2 = new Student("lihuangmin", 22);
    		Student s3 = new Student("xiaobaobei", 21);
    		Student s4 = new Student("xiaokeai", 25);
    		Student s5 = new Student("xifuer", 26);
    		Student s6 = new Student("luzhen", 22);
    		
    		//添加元素
    		ts.add(s1);
    		ts.add(s2);
    		ts.add(s3);
    		ts.add(s4);
    		ts.add(s5);
    		ts.add(s6);
    		
    		//遍历集合
    		for(Student s : ts) {
    			System.out.println(s.getName() + "," + s.getAge());
    		}
    	}
    }
    

    比较器排序:实现Comparator接口重写compare()方法
    这里以TreeMap为例,以匿名内部类方式实现Comparator接口

    package day18_Map_son_4;
    
    import java.util.Comparator;
    import java.util.Map;
    import java.util.Set;
    import java.util.TreeMap;
    
    /*
     * TreeMap<Student,String>
     */
    public class TreeMapDemo2 {
    	public static void main(String[] args) {
    		//创建集合对象
    		TreeMap<Student, String> tm = new TreeMap<Student,String>(new Comparator<Student>() {
    
    			@Override
    			public int compare(Student s1, Student s2) {
    				int num = s1.getAge() - s2.getAge();
    				int num2 = num==0?s1.getName().compareTo(s2.getName()):num;
    				return num2;
    			}
    		});
    		
    		//创建学生类对象
    		Student s1 = new Student("luzhen", 21);
    		Student s2 = new Student("lihuangmin",22);
    		Student s3 = new Student("luzhen", 21);
    		
    		//添加元素
    		tm.put(s1, "5120161818");
    		tm.put(s2, "5720161413");
    		tm.put(s3, "19970222");
    		
    		//遍历元素方式一
    		Set<Student> set = tm.keySet();
    		for(Student key : set) {
    			String value = tm.get(key);
    			System.out.println(key.getName() + "," + key.getAge() + "," + value);
    		}
    		
    		//遍历元素方式二
    		Set<Map.Entry<Student, String>> s = tm.entrySet();
    		for(Map.Entry<Student, String> m : s) {
    			Student key = m.getKey();
    			String value = m.getValue();
    			System.out.println(key.getName() + "," + key.getAge() + "," + value);
    		}
    	}
    }
    
    
    展开全文
  • 给大家介绍Java中的排序并不是指插入排序、希尔排序、归并排序等具体的排序算法。而是自然排序和比较器排序,文中通过实例代码介绍的很详细,有需要的朋友们可以参考借鉴。
  • TreeSet集合中自然排序和比较器排序概述和总结 *TreeSet():根据其元素的自然排序进行排序 *TreeSet( Comparator comparator) :根据指定的比较器进行排序 自然排序Comparable的使用 实现步骤 1.使用空参构造创建...

    TreeSet集合中自然排序和比较器排序概述和总结

    *TreeSet():根据其元素的自然排序进行排序
    *TreeSet( Comparator comparator) :根据指定的比较器进行排序

    自然排序Comparable的使用
    实现步骤
    1.使用空参构造创建TreeSet集合
    2.自定义的类实现Comparable接口
    自然排序,就是让元素所属的类实现Comparable接口,重写compareTo(T o)方法
    3. 重写接口中的compareTo方法
    重写方法时,一定要注意排序规则必须按照要求的主要条件和次要条件来写

    比较器排序Comparator的使用
    实现步骤
    比较器排序,就是让集合构造方法接收Comparator的实现类对象,重写compare(T o1,T o2)方法
    重写方法时,一定要注意排序规则必须按照要求的主要条件和次要条件来写
    两种比较方式总结
    1.用到的接口不同
    自然排序: 自定义类实现Comparable接口,重写compareTo方法,根据返回值进行排序
    ​比较器排序: 创建TreeSet对象的时候传递Comparator的实现类对象,重写compare方法,根据返回值进行排序
    ​2.使用场景不同
    ​自然排序能满足大部分情况
    当存储的元素类型中的比较规则 ,不满足需要,但是没法重写compareTo方法时可以使用(例如:改变包装类Integer的比较规则,让其从大到小)比较器排序
    3.相同点
    返回值的规则:

    • 如果返回值为负数,表示当前存入的元素是较小值,存左边
    • 如果返回值为0,表示当前存入的元素跟集合中元素重复了,不存
    • 如果返回值为正数,表示当前存入的元素是较大值,存右边
    展开全文
  • 自然排序和比较器排序 ​ 当指执行插入排序、希尔排序、归并排序等算法时,比较两个对象“大小”的比较操作。我们很容易理解整型的 i>j 这样的比较方式,但当我们对多个对象进行排序时,如何比较两个对象的“大小...
    TreeSet集合

    自然排序和比较器排序

    ​ 当指执行插入排序、希尔排序、归并排序等算法时,比较两个对象“大小”的比较操作。我们很容易理解整型的 i>j 这样的比较方式,但当我们对多个对象进行排序时,如何比较两个对象的“大小”呢?这样的比较 stu1 > stu2 显然是不可能通过编译的。为了解决如何比较两个对象大小的问题,JDK提供了两个接口java.lang.Comparablejava.util.Comparator

    TreeSet集合是Set集合的一个子实现类,它是基于TreeMap中的NavigableSet接口实现的
    TreeSet集合是默认通过自然排序将集合中的元素进行排序
    汉字的顺序根据Unicode 码表排序

    TreeSet有两种排序方式:

    1. 自然排序:java.lang.Comparable

      • Comparable 接口中只提供了一个方法: compareTo(Object obj),该方法的返回值是 int 。如果返回值为正数,则表示当前对象(调用该方法的对象)比 obj 对象“大”;反之“小”;如果为零的话,则表示两对象相等。
    2. 比较器排序:java.util.Comparator

    让我们先来看看一个例题:

    package com.xdkj.Test09;
    
    import java.util.TreeSet;
    
    public class TreeSetDemo {
    
        public static void main(String[] args) {
            TreeSet<Integer> set = new TreeSet<Integer>();
            set.add(17);
            set.add(25);
            set.add(23);
            set.add(14);
            set.add(17);
            set.add(30);
            for (Integer s : set) {
                System.out.println(s);
            }
        }
    }
    
    运行结果:
    14
    17
    23
    25
    30
    

    根据上述结果可以看出TreeSet集合是自然排序和去重的,为什么会达到这样的效果呢?

    TreeSet集合的无参构造就是属于自然排序

    TreeSet<Integer> set= new TreeSet<Integer>();
    

    这是因为TreeSet集合依赖于TreeMap的红黑树结构实现的,下面让我们根据上述例题去看看红黑树结构的理解:

    set.add(17);
    set.add(25);
    set.add(23);
    set.add(14);
    set.add(17);
    set.add(30);
    

    17先进行存储,所以将17作为根节点,与后面的元素进行比较,25进来后与17相比,比17大,所以成为17的右孩子,放在17的右边,23进来比17大所以要放在17的右边,但是和25比较比他小,所以放在25的左边,接下来1417小放在17的左边,17进来与17的值一样不理睬,继续下个30,比17大比25大,放在右边25 的右边,绘成图就是二叉图方式,结构一定是自平衡的

    使用TreeSet进行自定义函数的排序,对年龄由小到大进行排序

    package com.xdkj.Test09;
    
    public class Student implements Comparable<Student> {
    
        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 String toString() {
            return "Student{" +
                    "name='" + name + '\'' +
                    ", age=" + age +
                    '}';
        }
    
        //因为上面Student类实现了comparable接口,所以必须重写comparaTo方法才能达到排序的效果
        @Override
        public int compareTo(Student s) {
            // return 0;
            /**
             * 因为这是我们自定义的类,系统并没有告诉我们如何进行排序
             * 所以需要我们自己手动进行排序
             * 需求:按年龄由小到大进行排序
             */
            //年龄进行排序,由小到大
            int num = this.age - s.age;
            //当年龄大小相等时,比较名字
            int num2 = num == 0 ? this.name.compareTo(s.getName()) : num;
            return num2;
        }
    
    }
    
    package com.xdkj.Test09;
    
    import java.util.TreeSet;
    
    public class StudentDemo {
    
        public static void main(String[] args) {
            //创建TreeSet集合对象
            TreeSet<Student> set = new TreeSet<Student>();
            //创建学生对象,这里的学生姓名不要写成汉字,因为每个汉字的字节大小不一样
            Student s1 = new Student("dilireba", 27);
            Student s2 = new Student("gaowen", 25);
            Student s3 = new Student("zhaoxingxing", 24);
            Student s4 = new Student("wuxuanyi", 23);
            Student s5 = new Student("dilireba", 27);
            set.add(s1);
            set.add(s2);
            set.add(s3);
            set.add(s4);
            set.add(s5);
            //增强for循环
            for (Student st : set) { 
                System.out.println(st.getName() + "---" + st.getAge());
            }
        }
    }
    
    运行结果:
    wuxuanyi---23
    zhaoxingxing---24
    gaowen---25
    dilireba---27
    

    由上例可以看出我们在学生类上实线了comparable接口,并且在学生类中重写了comparaTo方法,当我们没有进行以上的这些操作时,运行时就会出现这样的错误,

    Exception in thread “main” java.lang.ClassCastException: com.TreeSetDome.Student cannot be cast to java.lang.Comparable

    因为没有实现comparable接口,所以会出现以上的这个异常,但是为什么在前面添加数字的时候并不需要实现comparable接口呢?这是添加数字时我们确定了类型为Integer类型,它本身就已经实现了comparable接口,不需要我们再去添加,具体可以去API中观看,所以今后在使用TreeSet创建自定义类排序的时候,一定要自己去实现comparable接口,和重写comparaTo方法

    上述中我们重写的ComparaTo方法是按照年龄来排序的,接下来让我们按照姓名的长度以及年龄的大小来排序:

    @Override
    public int compareTo(Student s) {
            /**
             * 因为这是我们自定义的类,系统并没有告诉我们如何进行排序
             * 所以需要我们自己手动进行排序
             * 需求:按姓名的长度来排序,然后再以年龄的大小来排序
             */
            //按姓名的长短来排序,由小到大排序
            int num = this.getName().length() - s.getName().length();
            //再去比较的姓名的内容是否一致
            int num2 = num == 0 ? this.getName().compareTo(s.getName()) : num;
            //名字一致,有时候并不是同一个人 还得再去比较年龄的大小
            int num3 = num2 == 0 ? this.age - s.age : num2;
            return num3;
            //这是重写的comparaTo方法,我新添加了一个学生变量 Student s6=new Student("dilireba",25);
        }
    
    运行结果:
    gaowen---25
    dilireba---25
    dilireba---27
    wuxuanyi---23
    zhaoxingxing---24
    

    上面我们介绍了自然排序法,自然排序法主要就是运用TreeSet的无参构造,通过实现comparable接口中的comparaTo方法去进行自然排序,接下来让我们看看比较器排序,看看二者的不同

    package com.xdkj.Test10;
    
    public class Student {
    
        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 String toString() {
            return "Student{" +
                    "name='" + name + '\'' +
                    ", age=" + age +
                    '}';
        }
    }
    
    
    package com.xdkj.Test10;
    
    import java.util.Comparator;
    
    public class ComparatorDome implements Comparator<Student> {
    
        /**
         * 因为测试类中TreeSet集合的引用参数是接口,所以需要创建这个 子实现类去实现这个接口
         * 这里的s1就相当于自然排序中的this,s2相当于s
         * 先按名字的长度,当长度一致时,再按年龄的大小进行排序
         */
        public int compare(Student s1, Student s2) {
    
            //判断姓名长度的大小
            int num = s1.getName().length() - s2.getName().length();
            //长度一致时,比较内容
            int num2 = num == 0 ? s1.getName().compareTo(s2.getName()) : num;
            //内容一致时,比较年龄的大小
            int num3 = num2 == 0 ? (s1.getAge() - s2.getAge()) : num2;
    
            return num3;
    
        }
    }
    
    package com.xdkj.Test10;
    
    import java.util.TreeSet;
    
    public class StudentDome {
    
    
        public static void main(String[] args) {
    
    
            //创建TreeSet集合对象,运用比较器排序
            //Comparator是一个接口,所以我们得创建一个子实现类去实现它
            TreeSet<Student> set = new TreeSet<Student>(new ComparatorDome());
            //创建学生对象
            Student s1 = new Student("dilireba", 27);
            Student s2 = new Student("gaowen", 25);
            Student s3 = new Student("zhaoxingxing", 24);
            Student s4 = new Student("wuxuanyi", 23);
            Student s5 = new Student("dilireba", 25);
            Student s6 = new Student("dilireba", 25);
            //将学生对象添加到集合中
            set.add(s1);
            set.add(s2);
            set.add(s3);
            set.add(s4);
            set.add(s5);
            set.add(s6);
    
            //增强for循环遍历
            for (Student s : set) {
                System.out.println(s.getName() + "---" + s.getAge());
            }
        }
    }
    
    运行结果:
    gaowen---25
    dilireba---25
    dilireba---27
    wuxuanyi---23
    zhaoxingxing---24
    

    除了创建子实现类去实现Comparator接口,我们还可以在测试类中通过匿名内部类的方式去测试,就不用单独去创建一个子实现类了

    在这里学生类我就不写了,上面有,直接写测试类中的匿名内部类了

    package com.xdkj.Test10;
    
    import java.util.Comparator;
    import java.util.TreeSet;
    
    /**
     * @Author:Lenvo
     * @Description:
     * @Date: 2020-12-16 16:21
     */
    public class StudentDome {
    
    
        public static void main(String[] args) {
            //创建TreeSet集合对象,运用比较器排序
            //Comparator是一个接口,所以我们得创建一个子实现类去实现它
            //匿名内部类的使用
            TreeSet<Student> set = new TreeSet<Student>(new Comparator<Student>() {
    
                @Override
                public int compare(Student s1, Student s2) {
                    //判断姓名长度的大小
                    int num = s1.getName().length() - s2.getName().length();
                    //长度一致时,比较内容
                    int num2 = num == 0 ? s1.getName().compareTo(s2.getName()) : num;
                    //内容一致时,比较年龄的大小
                    int num3 = num2 == 0 ? (s1.getAge() - s2.getAge()) : num2;
                    return num3;
                }
    
            });
            //创建学生对象
            Student s1 = new Student("dilireba", 27);
            Student s2 = new Student("gaowen", 25);
            Student s3 = new Student("zhaoxingxing", 24);
            Student s4 = new Student("wuxuanyi", 23);
            Student s5 = new Student("dilireba", 25);
            Student s6 = new Student("dilireba", 25);
            //将学生对象添加到集合中
            set.add(s1);
            set.add(s2);
            set.add(s3);
            set.add(s4);
            set.add(s5);
            set.add(s6);
            //增强for循环遍历
            for (Student s : set) {
                System.out.println(s.getName() + "---" + s.getAge());
            }
        }
    }
    
    运行结果:
    gaowen---25
    dilireba---25
    dilireba---27
    wuxuanyi---23
    zhaoxingxing---24
    
    
    展开全文
  • 1、自然排序和比较器排序 a 、先写一个Student的实体类 然后重写好toString()方法 hashCode()方法以及equals()方法 1、在Student类中右键---------》source------》Generate toString()... 就可找到toString()...

    1、自然排序和比较器排序

     a 、先写一个Student的实体类   然后重写好toString()方法  hashCode()方法 以及equals()方法

           1、在Student类中右键---------》source------》Generate  toString()... 

           就可找到toString()方法

          2、 在Student类中右键---------》source------》Generate  hashCode() and equals()... 

           可找到hashCode()方法和equals()方法

    package com.Reviewbj;
    
    public class Student implements  Comparable<Student>{
    
    private  int  id;
    private  String name;
    private  int  age;
    public int getId() {
    	return id;
    }
    public void setId(int id) {
    	this.id = id;
    }
    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;
    }
    public Student() {}
    public Student(int id, String name, int age) {
    	super();
    	this.id = id;
    	this.name = name;
    	this.age = age;
    }
    @Override
    public String toString() {
    	return "Student [id=" + id + ", name=" + name + ", age=" + age + "]";
    }
    @Override
    public int hashCode() {
    	final int prime = 31;
    	int result = 1;
    	result = prime * result + age;
    	result = prime * result + id;
    	result = prime * result + ((name == null) ? 0 : name.hashCode());
    	return result;
    }
    @Override
    public boolean equals(Object obj) {
    	if (this == obj)
    		return true;
    	if (obj == null)
    		return false;
    	if (getClass() != obj.getClass())
    		return false;
    	Student other = (Student) obj;
    	if (age != other.age)
    		return false;
    	if (id != other.id)
    		return false;
    	if (name == null) {
    		if (other.name != null)
    			return false;
    	} else if (!name.equals(other.name))
    		return false;
    	return true;
    }
    
    @Override
    public int compareTo(Student o) {
    
        return this.id-o.id;//按照学号排序
    
      //compareTo   用来比较   我与他比
    
      //根据学号的大小进行比较   
    
      //正数  负数  0   默认按照从小到大排列
    
     //this.id  当前的id   o.id  集合中的id
    
    }
    
    }
    

     b、再建一个MyCompareto.java的类  然后写好该方法  像下面这样

       

    package com.Reviewbj;
    
    import java.util.Comparator;
    
    public class MyCompareto implements Comparator<Student>{
    
    	@Override
    	public int compare(Student o1, Student o2) {
    	
            //按年龄排序
    
    		return o1.getAge()-o2.getAge();
    	}
    }
    

     

    c、再建一个demo.java类

          //排序  自然排序  比较器排序   如果两者同时存在  比较器排序的优先级别比自然排序高  

          //如果没有比较器  默认的排序方式是自然器排序   

    package com.Reviewbj;
    
    import java.util.Comparator;
    import java.util.HashSet;
    import java.util.Set;
    import java.util.TreeSet;
    
    public class Demo {
    
    public static void main(String[] args) {
     
    	//	Set<Student> s=new TreeSet<Student>(new MyCompareto());
    
    	//匿名内部类之比较器排序
    	Set<Student> s=new TreeSet<Student>(new  Comparator<Student>() {
    
    		@Override
    		public int compare(Student o1, Student o2) {
    			// TODO Auto-generated method stub
    			return  o1.getAge()-o2.getAge();
    			}
    		});
    	
            //给Student类中依次赋值
    		Student  s1=new Student(11, "hh", 23);
    		Student  s2=new Student(2, "xx", 13);
    		Student  s3=new Student(33, "zz", 14);
    		Student  s4=new Student(4, "kk", 45);
    		Student  s5=new Student(55, "dd", 34);
    
            //把对象添加到集合中
    		s.add(s1);
    		s.add(s2);
    		s.add(s3);
    		s.add(s4);
    		s.add(s5);
    
           //遍历
    
    		for (Student stu : s) {
    			System.out.println(stu);
    		}
    }
    
    }
    

      d、最后再运行demo.java类  结果是下面这样   基本上就没什么问题啦!

    Student [id=2, name=xx, age=13]
    Student [id=33, name=zz, age=14]
    Student [id=11, name=hh, age=23]
    Student [id=55, name=dd, age=34]
    Student [id=4, name=kk, age=45]

     

    展开全文
  • 05Java集合-13. TreeSet的自然排序和比较器排序*
  • 前言当指执行插入排序、希尔排序、归并排序等算法时,比较两个对象“大小”的比较操作。我们很容易理解整型的 i>j 这样的比较方式,但当我们对多个对象进行排序时,如何比较两个对象的“大小”呢?这样的比较 stu...
  • Java中的自然排序和比较器排序

    千次阅读 2019-01-13 14:53:28
    写在前面的话:刚开始学习着两者排序时我也是一头雾水,虽然能写出来但是稀里糊涂,几时该用哪个排序一点想法都没有,后来经过研究这两者的作用点不同,自然排序作用在实体类上,而比较器排序作用在装实体类的集合上...
  • Set接口类有三个子类:HashSet,LinkedListTreeSet; TreeSet底层数据结构是二叉树哈希表,所以能对元素...比较器排序(使用有参构造):传入一个比较器并实现它(可以定义一个类,实现比较器这个接口);另...
  • /*TreeSet集合是Set集合的一个子实现类,它是基于TreeMap中的NavigableSet接口实现的TreeSet集合是默认通过自然排序将集合中的元素进行排序TreeSet有两种排序方式: 1)自然排序 2)比较器排序*/ public class ...
  • 而是指执行这些排序算法时,比较两个对象“大小”的比较操作。我们很容易理解整型的 i>j 这样的比较方式,但当我们对多个对象进行排序时,如何比较两个对象的“大小”呢?这样的比较 stu1 > stu2 显然是不可能通过...
  • TreeSet集合TreeSet集合是Set集合的一个子实现类,它是基于TreeMap中的NavigableSet接口实现的TreeSet集合是默认通过自然排序将集合中的元素进行排序TreeSet有两种排序方式:1)自然排序2)比较器排序让我们先来看看...
  • 这里所说到的Java中的排序并不是指插入排序、希尔排序、归并排序等具体的...我们很容易理解整型的 i>j 这样的比较方式,但当我们对多个对象进行排序时,如何比较两个对象的“大小”呢?这样的比较 stu1 > s

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 635
精华内容 254
关键字:

自然排序和比较器排序