java的两种比较器:Compare接口和Compartor接口的学习总结


在java中,比较运算符(> , < , >= , <= , == , !=)可用于基本数据类型之间的比较,当我们要对两个对象进行比较时,只可以用 != 或者==来判断这两个对象是不是指向了内存中的同一个位置。 那么当我们要对类对象按照某种特定的方式进行排序时,该怎么办?
这里的某种特定的方式:比如说有好几个学生类对象,学生类中有身高,成绩,学号这些属性,对这些学生类对象进行排序的方式有好几种:按照学生的身高从高到低排序,或者是按照学生的成绩由高到低进行排序等等。

java提供了两种比较器来帮我们实现排序:Comapre接口和Comparator接口

实现Compar接口(自然排序):

Compare接口的使用 :
如果要对自定义的类进行排序,我们可以实现Comparable接口,并重compareTo()方法,在comparTo()方法中指明如何排序
像String,包装类已经实现了Comparable接口,重写了compareTo()方法,按照从小到大的顺序进行排序

重写compareTo(obj)的规则:
- 如果当前对象大于形参对象obj,返回正整数
- 如果当前对象小于形参对象obj,返回负整数
- 如果当前对象等于形参对象obj,返回0

import java.util.Arrays;
import java.util.Comparator;
//创建商品类,里面有商品价格,商品名两个私有属性
class Goods implements Comparable {
	
	private String name;
	private double price;
	
	public Goods(){
	}
	
	public Goods(String name, double price) {
		this.name = name;
		this.price = price;
	}
	
	public String toString() {
		return "Goods{name = "+name+"price = "+price+"}"+'\n';
	}
	
	public String geNmae() {
		return name;
	}
	
	public double getPrice() {
		return price;
	}
	//重写compareTo(Objext o)方法,对商品的价格从低到高进行排序
	public int compareTo(Object o) {
		if(o instanceof Goods) {	
			Goods anothergood = (Goods)o;
			if(this.price > anothergood.price) {
				return 1;
				//return Double.compare(this.price, anothergood.price);效果与上行是一样的
			}else if(this.price < anothergood.price) {
				return -1;
			}else {
				return this.name.compareTo(anothergood.name);
			}
		}
		else {//如果传入的数据类型不是商品类对象,那么抛出异常
			throw new RuntimeException("传入的数据类型不一致!");
		}
	}
}

public class CompareTest_01 {
	public static void main(String[] args) {
		
		Goods[] arrs = new Goods[6];
		arrs[0] = new Goods("levonomouse" , 55);
		arrs[1] = new Goods("dellmouse" , 45);
		arrs[2] = new Goods("xiaomimouse" , 70);
		arrs[3] = new Goods("applemouse" , 33);
		arrs[4] = new Goods("applemouse" , 343);
		arrs[5] = new Goods("huaweimouse" , 70);
		
		Arrays.sort(arrs);
		System.out.println(Arrays.toString(arrs));
	}
}

Comparator接口(定制排序):

为什么要Comparator接口:

  • 当元素类型没有实现java.lang.Comparable接口而又不方便修改代码
  • 实现了java.lang.Comparable接口的排序顺序不符合当前的操作需求,比如已经实现了Compareable接口的String类,但是我们又不要字符串按照从小到大的方式进行排序

重写compare(Object o1 , Object o2)方法,比较o1和o2的大小:
如果方法返回正值:表示o1>o2
如果方法返回负值:表示o1<o2
如果返回0:说明o1与o2相等

在这里插入图片描述
辅助类Array中有一个方法sort( T[] a , Comparator() comparator ),这个方法需要传入两个参数:需要进行排序的集合a,和一个实现Comparator接口的类对象。

package Compare_test;

import java.util.Arrays;
import java.util.Comparator;

class Goods implements Comparable {
	
	private String name;
	private double price;
	public Goods(){
		
	}
	public Goods(String name, double price) {
		this.name = name;
		this.price = price;
	}
	public String toString() {
		return "Goods{name = "+name+"price = "+price+"}"+'\n';
	}
	public String geNmae() {
		return name;
	}
	public double getPrice() {
		return price;
	}
}
//创建实现Comparator接口的类,指明商品的排序方式:先按照商品名从低到高排序,再按照商品价格从高到低排序
class GoodsComparator implements Comparator{
	 
    public int compare(Object o1, Object o2) {
		if(o1 instanceof Goods && o2 instanceof Goods) {
			Goods g1 = (Goods) o1;
			Goods g2 = (Goods) o2;
			return g1.geNmae().compareTo(g2.geNmae())==0? -Double.compare(g1.getPrice(), g2.getPrice()): g1.geNmae().compareTo(g2.geNmae());
		}else
			throw new RuntimeException("传入的两个数据类型不一致!");
	}
}

public class CompareTest_02 {
	public static void main(String[] args) {
		
		Goods[] arrs = new Goods[6];
		arrs[0] = new Goods("levonomouse" , 55);
		arrs[1] = new Goods("dellmouse" , 45);
		arrs[2] = new Goods("xiaomimouse" , 70);
		arrs[3] = new Goods("applemouse" , 33);
		arrs[4] = new Goods("applemouse" , 343);
		arrs[5] = new Goods("huaweimouse" , 70);

		GoodsComparator gc = new GoodsComparator();
		Arrays.sort(arrs,gc);
		System.out.println(Arrays.toString(arrs));
	}
}

我们还可以使用匿名内部类的方式来实现comapare(Object o1 , Object o2)方法:

//指明商品的排序方式:先按照商品名从低到高排序,再按照商品价格从高到低排序
Arrays.sort(arrs, new Comparator() {
			public int compare(Object o1 , Object o2) {
				if(o1 instanceof Goods && o2 instanceof Goods) {
					Goods g1 = (Goods) o1;
					Goods g2 = (Goods) o2;
					return g1.geNmae().compareTo(g2.geNmae())==0? -Double.compare(g1.getPrice(), g2.getPrice()): g1.geNmae().compareTo(g2.geNmae());
				}else
					throw new RuntimeException("传入的两个数据类型不一致!");
			}
		});

总结:Comparator更灵活

  • Comaparbale接口(重写compareTo(Object obj)方法)的排序方式一旦确定,就保证了Comaparbale接口实现类的对象在任何位置都能按照指定的顺序排序
  • Comparator接口(重写compare(Object o1 ,Object o2)方法)属于临时性的比较,在需要时就创建一个临时的匿名内部类,在里面定义排序的规则
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值