TreeSet之定制排序和自然排序

TreeSet的几大特点: 1、TreeSet中存储的类型必须是一致的,不能一下存int,一下又存string 2、TreeSet在遍历集合元素时,是有顺序的【从小到大】(我的理解,如果存的字母,按字典序排列) 3、排序:当向TreeSet中添加自定义对象时,有2种排序方法,1:自然排序  2、定制排序        自然排序:要求自定义类实现java.lang.Comparable接口并重写compareTo(Object obj)方法。在此方法中,指明按照自定义类的哪个属性进行排序

一、自然排序示例:             1、定义一个类(文章中为Employee)实现Comparable接口             2、重写Comparable接口中的compareTo()方法             3、在compareTo()中按指定属性进行排序(文章按name进行排序)代码示例:
Employee类
public class Employee implements Comparable{
     public int compareTo(Object o) {        if (o instanceof Employee) {            Employee e = (Employee) o;            return this.name.compareTo(e.name);        }        return 0;    }

private String name;    private int age;    private MyDate birthday;

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 MyDate getBirthday() {        return birthday;    }

public void setBirthday(MyDate birthday) {        this.birthday = birthday;    }

public Employee(String name, int age, MyDate birthday) {        this.name = name;        this.age = age;        this.birthday = birthday;    }

@Override    public String toString() {        return "Employee{" +                "name=‘" + name + ‘\‘‘ +                ", age=" + age +                ", birthday=" + birthday +                ‘}‘;    }

@Override    public boolean equals(Object o) {        if (this == o) return true;        if (o == null || getClass() != o.getClass()) return false;

Employee employee = (Employee) o;

if (age != employee.age) return false;        if (name != null ? !name.equals(employee.name) : employee.name != null) return false;        return birthday != null ? birthday.equals(employee.birthday) : employee.birthday == null;    }

@Override    public int hashCode() {        int result = name != null ? name.hashCode() : 0;        result = 31 * result + age;        result = 31 * result + (birthday != null ? birthday.hashCode() : 0);        return result;    }}

测试类
public class TreeSetTest {    public static void main(String[] args) {      test1();    }    /**     * 自然排序  按name排序 所以你的Employee必须实现Comparable接口     */    public static void test1() {        Employee e1 = new Employee("liudehua",55,new MyDate(4,12,1997));        Employee e2 = new Employee("11",55,new MyDate(5,12,1997));        Employee e3 = new Employee("22",55,new MyDate(6,12,1997));        Employee e4 = new Employee("33",55,new MyDate(7,12,1997));        Employee e5 = new Employee("44",55,new MyDate(8,12,1997));        TreeSet set = new TreeSet();        set.add(e1);        set.add(e2);        set.add(e3);        set.add(e4);        set.add(e5);

Iterator i = set.iterator();        while (i.hasNext()) {            System.out.println(i.next());        }    }}输出结果按name进行排序。按照汉语拼音的顺序

二、定制排序示例
Employee1 类
public class Employee1 {
    private String name;    private int age;    private MyDate birthday;

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 MyDate getBirthday() {        return birthday;    }

public void setBirthday(MyDate birthday) {        this.birthday = birthday;    }

public Employee1(String name, int age, MyDate birthday) {        this.name = name;        this.age = age;        this.birthday = birthday;    }

@Override    public String toString() {        return "Employee{" +                "name=‘" + name + ‘\‘‘ +                ", age=" + age +                ", birthday=" + birthday +                ‘}‘;    }

@Override    public boolean equals(Object o) {        if (this == o) return true;        if (o == null || getClass() != o.getClass()) return false;

Employee1 employee = (Employee1) o;

if (age != employee.age) return false;        if (name != null ? !name.equals(employee.name) : employee.name != null) return false;        return birthday != null ? birthday.equals(employee.birthday) : employee.birthday == null;    }

@Override    public int hashCode() {        int result = name != null ? name.hashCode() : 0;        result = 31 * result + age;        result = 31 * result + (birthday != null ? birthday.hashCode() : 0);        return result;    }}
MyDate类
public class MyDate {    private int day;    private int month;    private int year;

public int getDay() {        return day;    }

public void setDay(int day) {        this.day = day;    }

public int getMonth() {        return month;    }

public void setMonth(int month) {        this.month = month;    }

public int getYear() {        return year;    }

public void setYear(int year) {        this.year = year;    }

public MyDate(int day, int month, int year) {        this.day = day;        this.month = month;        this.year = year;    }

@Override    public String toString() {        return "MyDate{" +                "day=" + day +                ", month=" + month +                ", year=" + year +                ‘}‘;    }

//先重写MyDate的equals()和hashCode()方法,在重写Employee中的

@Override    public boolean equals(Object o) {        if (this == o) return true;        if (o == null || getClass() != o.getClass()) return false;

MyDate myDate = (MyDate) o;

if (day != myDate.day) return false;        if (month != myDate.month) return false;        return year == myDate.year;    }

@Override    public int hashCode() {        int result = day;        result = 31 * result + month;        result = 31 * result + year;        return result;    }}

测试类
public class TreeSetTest1 {    public static void main(String[] args) {          test2();    }    /**     * 定制排序  按指定生日来排     */    public static void test2() {        Comparator comparator = new Comparator() {            public int compare(Object o1, Object o2) {                if (o1 instanceof Employee1 && o2 instanceof Employee1) {                    Employee1 e1 = (Employee1)o1;                    Employee1 e2 = (Employee1)o2;

MyDate birth1 = e1.getBirthday();                    MyDate birth2 = e2.getBirthday();

if(birth1.getYear() != birth2.getYear()) {                        //定义的类型是 int  所以使用“-”减号代替compareTo()                        return birth1.getYear() - birth2.getYear();                    } else {                        if (birth1.getMonth() != birth2.getMonth()) {                            return birth1.getMonth() - birth2.getMonth();                        } else {                            return birth1.getDay() - birth2.getDay();                        }                    }                }                return 0;            }        };

// “一定要指明按特定对象进行比较  comparator参数一定要加”        TreeSet set = new TreeSet(comparator);        Employee1 e1 = new Employee1("liudehua",55,new MyDate(5,8,1990));        Employee1 e2 = new Employee1("11",55,new MyDate(5,11,1997));        Employee1 e3 = new Employee1("22",55,new MyDate(6,10,1997));        Employee1 e4 = new Employee1("33",55,new MyDate(7,9,1997));        Employee1 e5 = new Employee1("44",55,new MyDate(8,8,1997));        set.add(e1);        set.add(e2);        set.add(e3);        set.add(e4);        set.add(e5);

Iterator i = set.iterator();        while (i.hasNext()) {            System.out.println(i.next());        }    }}

总结:
自然排序实现的是comparable接口。其在类可以修改时使用。

定制排序实现的是comparator接口。其在类不可以修改时使用

在使用定制排序或是自然排序时,在其用到的类中都要重写hashCode()与equals()方法

comparable和comparator的区别:[参考博文:http://blog.csdn.net/excellentyuxiao/article/details/52344594]Comparator在util包下,Comparable在lang包下。java中的对象排序都是以comparable接口为标准的。comparator是在对象外部实现排序。


原文地址:https://www.cnblogs.com/kelly-one/p/8324775.html

时间: 2024-10-05 02:16:50

TreeSet之定制排序和自然排序的相关文章

Java基础知识强化之集合框架笔记44:Set集合之TreeSet保证元素唯一性和自然排序的原理和图解

1. TreeSet保证元素唯一性和自然排序的原理和图解

java TreeSet的排序之自然排序

TreeSet会调用元素的compareTo(Object o)方法来比较元素之间的大小关系,然后将集合里的元素按升序排列.此时需要排序元素的类必须实现Compareble接口,并覆写其int compareTo(Object o)方法; 该方法用于比较对象,若:obj1,compareTo(obj2),返回0,表示两个对象相等,若返回一个正整数,表示obj1大于obj2,若返回一个负整数,表示obj1小于obj2; 对于TreeSet集合而言,判断两个对象相等的标准是: compareTo()

分治算法——合并排序与自然排序

合并排序算法: public class MergeSort { public static void MergeSort(int A[],int low,int high){ if(low<high){ int middle=(low+high)/2; MergeSort(A,low,middle); MergeSort(A,middle+1,high); Merge(A,low,middle,high); } } public static void Merge(int A[],int lo

TreeSet ------自然排序与定制排序(比较器)

前言:TreeSet集合是Set集合的一个子实现类,它是基于TreeMap中的NavigableSet接口实现的,TreeSet集合是默认通过自然排序将集合中的元素进行排序 TreeSet有两种排序方式: 1)自然排序 2)比较器排序 1. 自然排序: 在TreeSet中默认要求里面的元素进行自然排序,强制要求里面的所有元素必须按照Comparable中的compareTo方法进行比较. 如果容器里面的对象不具备compareTo方法此时就会抛出异常报错,所以必须要让容器中的元素实现Compar

TreeSet联系 自然排序

****************************************************** 创建需要的两个类 package com.hu.treeset; public class MyDate { private int day; private int month; private int year; public int getDay() { return day; } public void setDay(int day) { this.day = day; } pu

Java基础知识强化之集合框架笔记45:Set集合之TreeSet存储自定义对象并遍历练习1(自然排序)

1. TreeSet存储自定义对象并遍历练习1(自然排序): (1)Student.java: 1 package cn.itcast_05; 2 3 /* 4 * 如果一个类的元素要想能够进行自然排序,就必须实现自然排序接口 5 */ 6 public class Student implements Comparable<Student> { 7 private String name; 8 private int age; 9 10 public Student() { 11 super

集合TreeSet(自然排序与定制排序)

一.TreeSet的自然排序: 步骤:让元素自身具备比较性, 实现Compareable接口,覆盖其CompareTo方法 class Student implements Comparable//第一:实现Compareable接口 { private String name; private int age; Student(String name,int age) { this.name = name; this.age = age; } public int compareTo(Obje

Java基础知识强化之集合框架笔记46:Set集合之TreeSet存储自定义对象并遍历练习2(自然排序)

1. TreeSet存储自定义对象并遍历练习2: (1)Student.java 1 package cn.itcast_06; 2 3 /* 4 * 如果一个类的元素要想能够进行自然排序,就必须实现自然排序接口 5 */ 6 public class Student implements Comparable<Student> { 7 private String name; 8 private int age; 9 10 public Student() { 11 super(); 12

TreeSet集合的add()方法源码解析(01.Integer自然排序)

>TreeSet集合使用实例 >TreeSet集合的红黑树 存储与取出(图) >TreeSet的add()方法源码     TreeSet集合使用实例 package cn.itcast_05; import java.util.TreeSet; /* * TreeSet:能够对元素按照某种规则进行排序. * 排序有两种方式 * A:自然排序 * B:比较器排序 * * TreeSet集合的特点:排序和唯一 * * 通过观察TreeSet的add()方法,我们知道最终要看TreeMap的