java小结_015_Treeset集合的compareTo和comparator

本文详细解释了如何使用Java中的TreeSet进行自然排序,并通过实现Comparable接口和自定义Comparator接口来定制排序逻辑。包括代码示例和原理说明。

TreeSet的排序之自然排序——compareTo

 

   TreeSet会调用元素的compareTo(Objecto)方法来比较元素之间的大小关系,然后将集合里的元素按升序排列.此时需要排序元素的类必须实现Compareble接口,并覆写其int compareTo(Objecto)方法;

该方法用于比较对象,若:obj1,compareTo(obj2),返回0,表示两个对象相等,若返回一个正整数,表示obj1大于obj2,若返回一个负整数,表示obj1小于obj2;

对于TreeSet集合而言,判断两个对象相等的标准是:

compareTo()方法比较返回 0;

 

<span style="font-size:18px;">//TreeSet可以自动进行排序!最简单的情况
 
import java.util.*;
 
public class Demo {
    publicstatic void main(String[] args) {
      
       Set<Integer>s = new TreeSet<Integer>();
       s.add(1);
       s.add(192);
       s.add(123);
      
       System.out.println(s);//[1, 123, 192]
    }
}
 
稍复杂点的
 
//TreeSet的自然排序,升序
 
import java.util.Set;
import java.util.TreeSet;
 
class Student implements Comparable{//必须实现接口
    private Integer age;
 
    public Student(Integer age) {
       super();
       this.age = age;
    }
 
    @Override
    public int compareTo(Object o) {//比较的规则,运用泛型可以消除强转!
       if(o instanceof Student){
           Student s = (Student)o;
           return this.age.compareTo(s.age);
       }
       return 0;
    }
 
    @Override
    public String toString() {
       return age+"" ;
    }
}
 
public class Demo14 {
    public static void main(String[] args) {
      
       Set<Student> s = new TreeSet();
       s.add(new Student(140));
       s.add(new Student(15));
       s.add(new Student(11));
       s.add(new Student(63));
       s.add(new Student(96));
       System.out.println(s);//[11, 15, 63, 96, 140]
    }
}</span>


 

 

TreeSet的排序之定制排序——Comparator

 

TreeSet的自然排序是根据元素的大小进行升序排序的,若想自己定制排序,比如降序排序,就可以使用Comparator接口了:

必须实现Comparator接口,并覆写其public intcompare(Object o1, Object o2)方法该int compare(Object o1,Object o2)方法,用于比较两个对象的大小,比较结果和compareTo方法一致;

要实现定制排序,需要在创建TreeSet集合对象时,提供一个一个Comparator对象,该对象里负责集合元素的排序逻辑;

TreeSet(Comparator comparator)

 

<span style="font-size:18px;">//定制排序的话,必须在创建TreeSet集合对象的时候提供一个Comparator方法
 
import java.util.*;
 
class Student1{
    private Integer age;
   
    public Student1(Integer age) {
       super();
       this.age = age;
    }
 
    public Integer getAge() {
       return age;
    }
 
    public void setAge(Integer age) {
       this.age = age;
    }
 
    @Override
    public String toString() {
       return age + "";
    }
}
 
class MyComparator implements Comparator{
   
    @Override
    public int compare(Object o1, Object o2) {
       if(o1 instanceof Student1 & o2 instanceof Student1){
           Student1 s1 = (Student1)o1;
           Student1 s2 = (Student1)o2;
           if(s1.getAge() >s2.getAge()){
              return -1;
           }else if(s1.getAge() < s2.getAge()){
              return 1;
           }
       }
       return 0;
    }
}
 
public class Demo {
    public static void main(String[] args) {
       Set<Student1> s = new TreeSet(new MyComparator());
       /**
        * 要实现定制排序,需要在创建TreeSet集合对象时,提供一个一个Comparator对象,
        * 该对象里负责集合元素的排序逻辑;
        */
       s.add(new Student1(140));
       s.add(new Student1(15));
       s.add(new Student1(11));
       s.add(new Student1(63));
       s.add(new Student1(96));
      
       System.out.println(s);
    }
}
 </span>
### Java TreeSet 中自定义排序重写 compareTo 方法 在 `TreeSet` 使用过程中,为了实现自定义排序功能,通常有两种方式:一种是通过让元素类实现 `Comparable` 接口并重写 `compareTo()` 方法;另一种是在创建 `TreeSet` 实例时提供一个实现了 `Comparator` 接口的对象。 #### 方式一:实现 Comparable 接口 当希望某个特定类型的对象能够默认按某种逻辑被排序时,可以在该类型本身中实现 `Comparable<T>` 接口,并指定泛型参数 T 为自己所属的类。接着,在此类内编写具体的比较规则即 `compareTo(E other)` 函数体[^1]。 下面是一个简单的例子来展示如何在一个表示学生的类 (`Student`) 中实现此接口: ```java import java.util.*; class Student implements Comparable<Student> { private String name; private int age; public Student(String n, int a){ this.name = n; this.age = a; } @Override public int compareTo(Student s) { // 按年龄升序排列学生列表 return Integer.compare(this.age, s.age); } @Override public String toString(){ return "Name: "+this.name+", Age:"+this.age; } } // 测试代码片段 public class Main{ public static void main(String[] args){ Set<Student> set = new TreeSet<>(); set.add(new Student("Alice", 20)); set.add(new Student("Bob", 22)); System.out.println(set); } } ``` 在这个例子中,每当向 `TreeSet` 添加新的 `Student` 对象实例时,都会调用其自身的 `compareTo()` 来决定新成员应该放置的位置[^3]。 #### 方式二:使用 Comparator 接口 对于不想修改原有类结构的情况或是需要多种不同的排序标准,则可以通过传递给 `TreeSet` 构造函数一个匿名内部类或 lambda 表达式的 `Comparator<? super E>` 参数来进行定制化处理[^5]。 这里给出一段基于上述 `Student` 类但是采用外部比较器的方式来做降序排序的例子: ```java import java.util.*; class Student { private String name; private int age; public Student(String n, int a){ this.name = n; this.age = a; } @Override public String toString(){ return "Name: "+this.name+", Age:"+this.age; } } // 测试代码片段 public class Main{ public static void main(String[] args){ Set<Student> set = new TreeSet<>(new Comparator<Student>() { @Override public int compare(Student s1, Student s2) { return Integer.compare(s2.getAge(), s1.getAge()); // 按照年龄倒叙排列 } }); set.add(new Student("Charlie", 24)); set.add(new Student("David", 28)); System.out.println(set); } } ``` 这种方式允许更加灵活地控制排序行为而无需改变原始数据模型的设计[^2]。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值