Comparable 接口和 Comparator 接口的实现(十一)

该博客介绍了Java中对象比较用到的Comparable和Comparator接口。通过创建User类,分别展示了这两个接口的使用方法,包括实现接口、重写方法及测试。还对比了二者区别,如实现方式、比较对象等,建议使用Comparator接口。

上一章简单介绍了Desktop桌面类的使用(十),如果没有看过,请观看上一章

一. 比较接口

在Java 中, 有普通数值的比较 ,如比较运算符 > < , 3>4, 也有字符串的比较值, 如String 类中的compare() 方法, 当然也有对象之间的比较。 对象之间的比较 用到的是Comparable 接口或者是 Comparator 接口。

其中, Comparable 接口的定义是:

package java.lang;
import java.util.*;
public interface Comparable<T> {
    public int compareTo(T o);
}

只有一个 compare() 的方法,是自身的比较。

Comparator 接口的定义是:


package java.util;
import java.io.Serializable;
import java.util.function.Function;
import java.util.function.ToIntFunction;
import java.util.function.ToLongFunction;
import java.util.function.ToDoubleFunction;
import java.util.Comparators;
@FunctionalInterface
public interface Comparator<T> {
   //主要接口. 
    int compare(T o1, T o2);
	
    boolean equals(Object obj);
}

现在,创建一个用户类 User, 里面有 年龄和成绩的属性, 根据成绩和年龄进行相应的排序。
先按照 成绩从高到低排序,如果成绩一样,那么就按照年龄排序,年龄小的在前面。

二. 创建类 User

package com.yjl.compa;
/**
@atuhor:两个蝴蝶飞
@Description: 类User
*/
public class User {
	/**
	 * @param id id编号
	 * @param name 姓名
	 * @param age 年龄
	 * @param score 成绩
	 * @param description 描述
	 */
	private int id;
	private String name;
	private int age;
	private double score;
	private String description;
	public User(int id, String name, int age, double score, String description) {
		super();
		this.id = id;
		this.name = name;
		this.age = age;
		this.score = score;
		this.description = description;
	}
	public User(){
		super();
	}
	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 String getDescription() {
		return description;
	}
	public void setDescription(String description) {
		this.description = description;
	}
	
	public double getScore() {
		return score;
	}
	public void setScore(double score) {
		this.score = score;
	}
	@Override
	public String toString() {
		return "User [id=" + id + ", name=" + name + ", age=" + age + ", score=" + score + ", description="
				+ description + "]";
	}
	
	
}

三. Comparable 接口的使用

三.一 让比较类 User 实现 Comparable 接口

public class User implements Comparable<User>{
	
}

三.二 重写 comareTo() 接口。

@Override
	public int compareTo(User user) {
		if(this.score>user.score){
			return -1;
		}else if(this.score<user.score){
			return 1;
		}else{  //成绩相同,按照年龄进行排序
			if(this.age>user.age){
				return 1;
			}else if(this.age<user.age){
				return -1;
			}else{
				return 0;
			}
		}
	}

这样的话, 这个用户类 User 就可以进行比较了。 会先按照成绩进行排序,再按照年龄排序。

三.三 测试方法 用数组测试

package com.yjl.test;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

import org.junit.Before;
import org.junit.Test;

import com.yjl.compa.MyComparator;
import com.yjl.compa.StringComparator;
import com.yjl.compa.User;
/**
@atuhor:两个蝴蝶飞
@Description: 类描述
*/
public class CompaTest {
	private List<User> allUser=new ArrayList<User>();
	private User[] allArr=null;
	@Before
	public void initUserList(){
		User user1=new User(1,"蝴蝶飞",24,98.0,"这是蝴蝶飞");
		User user2=new User(2,"两个蝴蝶飞",24,99.0,"这是两个蝴蝶飞");
		User user3=new User(3,"精灵妹",24,100.0,"这是精灵妹");
		User user4=new User(4,"精灵",24,97.0,"这是精灵");
		User user5=new User(5,"张三",25,98.0,"这是张三");
		User user6=new User(6,"李四",25,99.0,"这是李四");
		User user7=new User(7,"驭风",25,100.0,"这是驭风");
		User user8=new User(8,"墨",25,97.0,"这是墨");
		User user9=new User(9,"周",25,96.0,"这是周");
		allUser.add(user1);
		allUser.add(user2);
		allUser.add(user3);
		allUser.add(user4);
		allUser.add(user5);
		allUser.add(user6);
		allUser.add(user7);
		allUser.add(user8);
		allUser.add(user9);
		
		//转换成数组
		allArr=allUser.toArray(new User[]{});
	}
	@Test
	public void testA(){
		// System.out.println(allArr.length); //有值,9,说明转换成功。
		System.out.println("排序之前输出:");
		for(User u:allArr){
			System.out.println(u);
		}
		Arrays.sort(allArr);  /*从小到大排*/
		System.out.println("排序之后输出:");
		for(User u:allArr){
			System.out.println(u);
		}
	}
}

日志输出:
在这里插入图片描述
排序之前,是按照 id 编号 进行输出,排序之后, 会按照成绩 和年龄进行相应的排序。

四. Comparator 接口

User 类 保持不变,与第二步的 User 一样,是一个简单的User 类。

四.一 新建新的排序类,实现 Comparator 接口

新建一个MyComparator 的类, 实现接口,重写里面的comparator 方法。

package com.yjl.compa;

import java.util.Comparator;

/**
@atuhor:两个蝴蝶飞
@Description: 类描述
*/
public class MyComparator implements Comparator<User>{

	@Override
	public int compare(User u1, User u2) {
		if(u1.getScore()>u2.getScore()){
			return -1;
		}else if(u1.getScore()<u2.getScore()){
			return 1;
		}else{  //成绩相同,按照年龄进行排序
			if(u1.getAge()>u2.getAge()){
				return 1;
			}else if(u1.getAge()<u2.getAge()){
				return -1;
			}else{
				return 0;
			}
		}
	}

}

四.二 测试方法 用集合测试

package com.yjl.test;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

import org.junit.Before;
import org.junit.Test;

import com.yjl.compa.MyComparator;
import com.yjl.compa.StringComparator;
import com.yjl.compa.User;
/**
@atuhor:两个蝴蝶飞
@Description: 类描述
*/
public class CompaTest {
	private List<User> allUser=new ArrayList<User>();
	private User[] allArr=null;
	@Before
	public void initUserList(){
		User user1=new User(1,"蝴蝶飞",24,98.0,"这是蝴蝶飞");
		User user2=new User(2,"两个蝴蝶飞",24,99.0,"这是两个蝴蝶飞");
		User user3=new User(3,"精灵妹",24,100.0,"这是精灵妹");
		User user4=new User(4,"精灵",24,97.0,"这是精灵");
		User user5=new User(5,"张三",25,98.0,"这是张三");
		User user6=new User(6,"李四",25,99.0,"这是李四");
		User user7=new User(7,"驭风",25,100.0,"这是驭风");
		User user8=new User(8,"墨",25,97.0,"这是墨");
		User user9=new User(9,"周",25,96.0,"这是周");
		allUser.add(user1);
		allUser.add(user2);
		allUser.add(user3);
		allUser.add(user4);
		allUser.add(user5);
		allUser.add(user6);
		allUser.add(user7);
		allUser.add(user8);
		allUser.add(user9);
		
		//转换成数组
		allArr=allUser.toArray(new User[]{});
	}
	@Test
	public void testB(){
		System.out.println("排序之前:");
		allUser.forEach(n ->System.out.println(n));
		allUser.sort(new MyComparator());
		System.out.println("排序之后:");
		allUser.forEach(n ->System.out.println(n));
	}
}

控制台输出为:
在这里插入图片描述
可以正常的排序。

五. Comparable 和Comparator 接口的区别

  1. Comparable 接口 实现简单, 直接 在实体类中 实现 该接口,重写里面的规则方法即可,而Comparator 接口却需要新建一个类,才重新该方法。
  2. Comparable 是内比较器,是这个类的 当前对象与另外一个对象进行比较,而Comparator 是外比较器, 是某个类 的两个不同的对象进行比较。
  3. Comparable 一般用于 创建类的同时 进行创建排序规则, 而Comparator 是类创建完成之后好久,需求改变排序。
  4. 改变时,如果Comparable 时,想要改变规则,如按照名称和年龄进行排序,则需要修改 User 中compareTo 的代码实现,而Comparator 不需要,只需要新建一个名称和年龄的排序类即可,然后在集合排序时,将这个名称和年龄的类放入进去即可。适用于可能存在多个规则的情况下。

建议使用 Comparator 接口。

谢谢!!!

### Java 中 `Comparable` `Comparator` 接口区别及用法 #### 定义与用途 `Comparable<T>` 是一个内置接口,用于定义对象的自然顺序。当类实现接口时,意味着该类的对象可以按照某种逻辑进行比较。通常情况下,这种逻辑基于某个属性,比如字符串按字母顺序排列或数值类型的大小。 ```java public class Employee implements Comparable<Employee> { private String name; private int age; // Constructor, getters and setters omitted for brevity @Override public int compareTo(Employee other) { return Integer.compare(this.age, other.getAge()); } } ``` 相比之下,`Comparator<T>` 提供了一种灵活的方式来指定额外的排序标准而无需修改原始类的设计。这允许开发者在同一组数据上应用不同的排序策略[^3]。 ```java import java.util.Comparator; public class AgeSorter implements Comparator<Employee> { @Override public int compare(Employee o1, Employee o2) { return o1.getAge() - o2.getAge(); } } ``` #### 使用场景 - **`Comparable`**: 当希望给定类型的实例具有固定的、内在的排序方式时使用。例如,在集合框架中存储自定义对象并期望它们能够自动排序的情况下非常有用。 - **`Comparator`**: 如果需要根据不同条件动态改变排序行为,则更适合采用这种方式。它还可以用来处理那些无法控制其源码的情况下的外部类排序需求。 通过上述两种方法之一来定制化排序机制,可以使程序更加模块化且易于维护。值得注意的是,虽然两者都可以完成相似的任务,但在具体应用场景下各有优劣。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

两个蝴蝶飞

你的鼓励,是老蝴蝶更努力写作的

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值