Java中Comparable和Comparator的使用

Comparable 外部比较器  在java.lang包内  自然排序

以学生类为例,包含属性,构造方法,hashcode,equals方法等

public class Student {
	public String name;
	public int id;

	public Student(String name, int id) {
		super();
		this.name = name;
		this.id = id;
	}

	@Override
	public int hashCode() {
		final int prime = 31;
		int result = 1;
		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 (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 String toString() {
		return "姓名=" + name + ", 学号=" + id;
	}
}
import java.util.Comparator;
import java.util.Set;
import java.util.TreeSet;
import org.junit.Test;

public class TestStudent{

	@Test
	public void testComparable() {
		Set<Student> s1 = new TreeSet<>();
		s1.add(new Student("bb", 3));
		s1.add(new Student("bb", 3));
		s1.add(new Student("cc", 2));
		s1.add(new Student("aa", 1));
		System.out.println(s1);
	}
}

会有java.lang.ClassCastException: org.witer.Student cannot be cast to java.lang.Comparable异常;意思是学生类型转换为Comparable类型失败

让学生类实现Comparable接口,重写compareTo方法,代码如下

import java.util.Comparator;
import java.util.Set;
import java.util.TreeSet;
import org.junit.Test;

public class Student implements Comparable<Student> {
	public String name;
	public int id;

	public Student(String name, int id) {
		super();
		this.name = name;
		this.id = id;
	}

	// 计算hash值是否相等
	@Override
	public int hashCode() {
		final int prime = 31;
		int result = 1;
		result = prime * result + id;
		result = prime * result + ((name == null) ? 0 : name.hashCode());
		return result;
	}

	// 若hash值相等,用equals判断是否相等
	@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 (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 String toString() {
		return "姓名=" + name + ", 学号=" + id;
	}

	// 改写compareTo方法
	@Override
	public int compareTo(Student o) {
		// 定义一个变量bj 将传入的参数和自己比较
		int bj = this.id > o.id ? 1 : (this.id == o.id ? 0 : -1);
		// 若id值相同,则用姓名的自然排序
		if (bj == 0) {
			bj = this.name.compareTo(o.name);
		}
		return bj;
	}
}
Console  输出:[姓名=aa, 学号=1, 姓名=cc, 学号=2, 姓名=bb, 学号=3]


Comparator 内部比较器  在java.util包内   定制排序

以人类为例,参照学生类,也可以实现Comparator接口,重写compare方法,但是这样浪费了资源(一个类)

所以可以在外部写一个比较器,调用比较器解决问题

public class Person {
	private String name;
	private int 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;
	}

	public Person(String name, int age) {
		super();
		this.name = name;
		this.age = age;
	}

	@Override
	public int hashCode() {
		final int prime = 31;
		int result = 1;
		result = prime * result + age;
		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;
		Person other = (Person) obj;
		if (age != other.age)
			return false;
		if (name == null) {
			if (other.name != null)
				return false;
		} else if (!name.equals(other.name))
			return false;
		return true;
	}

	@Override
	public String toString() {
		return "姓名=" + name + ", 年龄=" + age;
	}
}
import java.util.Comparator;
import java.util.Set;
import java.util.TreeSet;
import org.junit.Test;

public class TestStudent{
	
	@Test
	public void testComparator(){
		//定义一个比较器
		Comparator<Person> com=new Comparator<Person>() {
			@Override
			//重写compare方法
			public int compare(Person o1, Person o2) {
				//定义一个变量接收比较值
			int b=o1.getAge()>o2.getAge()?1:(o1.getAge()==o2.getAge()?0:-1);
				//如果年龄相等,按姓名的自然排序
				if(b==0){
					b=o1.getName().compareTo(o2.getName());
				}
				return b;
			}
		};
		//创建集合并调用比较器
		Set<Person>p1=new TreeSet<>(com);
		p1.add(new Person("cc", 15));
		p1.add(new Person("aa", 28));
		p1.add(new Person("aa", 12));
		p1.add(new Person("bb", 15));
		System.out.println(p1);
		
	}
}

Console显示   [姓名=aa, 年龄=12, 姓名=bb, 年龄=15, 姓名=cc, 年龄=15, 姓名=aa, 年龄=28]

什么时候使用定制排序?

答:1,当自然排序和定制排序都存在时,优先使用定制排序

       2,当集合不支持自身比较器或者不满足程序员需求时


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
JavaComparableComparator都是用于进行对象比较的接口。它们的用法如下: 1. Comparable接口 Comparable接口是Java内置的接口,它包含一个方法compareTo(),用于比较对象的大小。实现该接口的类可以直接进行排序。 例如,我们定义一个Person类实现Comparable接口: ``` public class Person implements Comparable<Person> { private String name; private int age; public Person(String name, int age) { this.name = name; this.age = age; } public int compareTo(Person person) { // 按照年龄进行排序 return this.age - person.age; } } ``` 在这个例子,我们通过实现Comparable接口,并重写compareTo()方法,按照年龄进行排序。 使用Comparable接口进行排序的例子: ``` List<Person> list = new ArrayList<Person>(); list.add(new Person("Tom", 20)); list.add(new Person("Jerry", 18)); list.add(new Person("Jack", 25)); Collections.sort(list); for(Person p : list) { System.out.println(p.getName() + " " + p.getAge()); } ``` 输出结果: ``` Jerry 18 Tom 20 Jack 25 ``` 2. Comparator接口 Comparator接口也是Java内置的接口,它包含一个方法compare(),用于比较两个对象的大小。实现该接口的类可以定制不同的比较规则。 例如,我们定义一个PersonComparator类实现Comparator接口: ``` public class PersonComparator implements Comparator<Person> { public int compare(Person p1, Person p2) { // 按照姓名进行排序 return p1.getName().compareTo(p2.getName()); } } ``` 在这个例子,我们通过实现Comparator接口,并重写compare()方法,按照姓名进行排序。 使用Comparator接口进行排序的例子: ``` List<Person> list = new ArrayList<Person>(); list.add(new Person("Tom", 20)); list.add(new Person("Jerry", 18)); list.add(new Person("Jack", 25)); Collections.sort(list, new PersonComparator()); for(Person p : list) { System.out.println(p.getName() + " " + p.getAge()); } ``` 输出结果: ``` Jack 25 Jerry 18 Tom 20 ``` 总之,ComparableComparator都是用于对象比较的接口。使用Comparable接口可以方便地对实现该接口的对象进行排序,而使用Comparator接口可以定制不同的比较规则。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值