集合--比较器

二、比较器

1、什么是比较器

在java中有两个常用的比较器,分别是Comparator接口和Comparable接口, 他们都可以完成自定义排序,但是在使
用中,这两个比较器不管是在书写上还是侧重点上,都有不小的区别。

2、两种比较器接口的区别

Comparator 临时排序 可以在不同的排序之间切换

Comparable 永久排序

其他就不记忆了

➢Comparable接口是在lang包里的, 不需要额外导包; Comparator接口是在util包里的,需要你进行导包;
➢Comparable接口让实现 了他的子类具备某个固定的排序方式,比如String类实现 了Comparable接口之后,它的排序规
则就是一个个字母的比较;而Comparator接口是一 种比较灵活的比较方式,它属于一种临时比较的方式,我们可以在A
场景下使用这种排序,在B场景下又去使用另外一种排序;
➢Comparable接口下的方法是compareTo方法, 只有一个参数,代表的是当前对象本身与参数的比较;而Comparator接
口下的方法是compare方法,里面有两个参数,代表的是两个两个的比较;
➢Comparable接口我们都是 直接用在一个需要具有排序规则的类上,而Comparator接口我们都是以匿名内部类的形式写
在Arrays.sort和Collections.sort方法里面来临时性的对某个集合对象进行排序;
➢实现Comparable接口并且重写了排序规则的类对象可以放在TreeSet中完成排序或者是通过Arrays.sort或者是
Collections.sort完成排序,而实现Comparator接 口的临时排序规则就只用在Arrays/Collections.sort(obj,排序规则对
象)。

三、Comparable的使用

public class TreeSetDemo {
	public static void main(String[] args) {
		TreeSet<Student> set4 = new TreeSet<Student>();
		set4.add(new Student("zhangsan",19));
		set4.add(new Student("lisi",20));
		set4.add(new Student("wangwu",21));
		System.out.println(set4);
	}
}
class Student implements Comparable<Student>{
	static int num = 0;
	String name;
	int age;
	public Student(String name, int age) {
		super();
		this.name = name;
		this.age = age;
	}
	@Override
	public String toString() {
		return "Student [name=" + name + ", age=" + age + "]";
	}
	@Override
	public int compareTo(Student o) {
		//当你返回0的时候,代表这些对象相同;
		//当你返回正数的时候,代表着是该属性值的升序-->本身.属性-参数.属性
		//当你返回负数的时候,代表的是该属性值的降序-->参数.属性-本身.属性
		System.out.println("开始比较了第"+num+++"次");
//		return o.age-this.age;
//		return this.name.charAt(0)-o.name.charAt(0);
		return o.name.length()-this.name.length();
	}
}
/**
 * 
 * Comparable的运用
 * 1、当我们一个类已经实现了Comparable接口之后,并且重写了
 * 里面的comparaTo方法时,那就证明该类已经具有了一个排序规则;
 * 2、这个排序规则可以运用在以下几个场合:
 * 		a、TreeSet;
 * 		b、Arrays.sort;
 * 		c、Collections.sort;
 *
 */
public class ComparableDemo {
	public static void main(String[] args) {
		//构建一个元素是Student类型的TreeSet对象
		TreeSet<Student> set = new TreeSet<Student>();
		set.add(new Student("zhangsan",19));
		set.add(new Student("lisi",20));
		set.add(new Student("wangwu",21));
		System.out.println(set);
		System.out.println("--------------------------------");
		//构建一个Student的数组
		Student [] stus = new Student[3];
		stus[0] = new Student("zhangsan",19);
		stus[1] = new Student("lisi",20);
		stus[2] = new Student("wangwu",21);
		System.out.println(Arrays.toString(stus));
		Arrays.sort(stus);
		System.out.println(Arrays.toString(stus));
		System.out.println("--------------------------------");
		//构建一个Student的集合
		ArrayList<Student> list = new ArrayList<Student>();
		list.add(new Student("zhangsan",19));
		list.add(new Student("lisi",20));
		list.add(new Student("wangwu",21));
		System.out.println(list);
		Collections.sort(list);
		System.out.println(list);
		
	}
}

四、Comparator临时比较器的使用

  • Comparator比较器的使用

  • 1、该比较器适用于临时的比较场合;

  • 2、该比较器里面的方法是compare,它和Comparable里面的

    compareTo里面的参数个数是不一样的,但是你可以把compare

    里面的第一个参数,看成是compareTo里面的this就很容易理解了;

  • 3、Comparator因为是一个临时的排序规则,所以我们一般都是在

    Arrays.sort以及Collections.sort里面来使用它;不能在TreeSet里面完成排序;

  • 4、我们在使用过程中,发现,一个比较规则的类只是用来使用它的一次方法的话

    太过于消耗资源,那么我们能不能进行一个简化呢?使用匿名内部类

1、演示

public class ComparaTorDemo {
	public static void main(String[] args) {
		//构建一个Teacher的数组
		Teacher [] stus = new Teacher[3];
		stus[0] = new Teacher("zhangsan",19);
		stus[1] = new Teacher("lisi",20);
		stus[2] = new Teacher("wangwu",21);
		System.out.println(Arrays.toString(stus));
		Arrays.sort(stus,new MySort1());
		System.out.println(Arrays.toString(stus));
		System.out.println("--------------------------------");
		//构建一个Teacher的集合
		ArrayList<Teacher> list = new ArrayList<Teacher>();
		list.add(new Teacher("zhangsan",19));
		list.add(new Teacher("lisi",20));
		list.add(new Teacher("wangwu",21));
		System.out.println(list);
		Collections.sort(list,new MySort1());
		System.out.println(list);
		System.out.println("--------------------------------");
    // 临时体现这里,在这里使用可以将compare方法重写
		Collections.sort(list,new Comparator<Teacher>() {
			@Override
			public int compare(Teacher o1, Teacher o2) {
				return o2.name.length()-o1.name.length();
			}
		});
		System.out.println(list);
	}
}
class MySort1 implements Comparator<Teacher>{
  //按照名字首字母
	@Override
	public int compare(Teacher o1, Teacher o2) {
		return o2.name.charAt(0)-o1.name.charAt(0);
	}
}
//按照名字长度排序
//class MySort implements Comparator<Teacher>{
//	@Override
//	public int compare(Teacher o1, Teacher o2) {
//		return o2.name.length()-o1.name.length();
//	}
//}
class Teacher{
	int age;
	String name;
	public Teacher(String name, int age) {
		super();
		this.name = name;
		this.age = age;
	}
	@Override
	public String toString() {
		return "Teacher [name=" + name + ", age=" + age + "]";
	}
}

五、案例

1.让一个字符串数组的排序规则为最后一个字母的升序。
2.完成Student类的自定义排序:
a)构建一个Student类 ,该类里面有两个属性,分别是name和age。
b)要求分别使用Comparable和Comparator来完成该类对 象的自定义排序:按照age的降序排列,
如果age相同,则按照name的升序排列。

public class Work {
	public static void main(String[] args) {
		work1();
		work2();
	}

	private static void work2() {
		ArrayList<Student1> list = new ArrayList<Student1>();
		//Collections.addAll()
		Collections.addAll(list, new Student1("zhaoliu",20),
				new Student1("zhangsan",19),
				new Student1("lisi",20),
				new Student1("wangwu",20)
				);
		Collections.sort(list);
		System.out.println(list);
		ArrayList<Student2> list2 = new ArrayList<Student2>();
		//Collections.addAll()
		Collections.addAll(list2, new Student2("zhaoliu",20),
				new Student2("zhangsan",19),
				new Student2("lisi",20),
				new Student2("wangwu",20)
				);
		Collections.sort(list2, new Comparator<Student2>() {
			@Override
			public int compare(Student2 o1, Student2 o2) {
				if(o1.age==o2.age) {
					//如果年龄相同的话,那么使用name的首字母升序
					return o1.name.charAt(0)-o2.name.charAt(0);
				}
				return o2.age-o1.age;
			}
		});
		System.out.println(list2);
	}
//1.让一个字符串数组的排序规则为最后一个字母的升序。
	private static void work1() {
		String [] arr = {"abc","cba","dab"};
		Arrays.sort(arr,new Comparator<String>() {
			@Override
			public int compare(String o1, String o2) {
				return o1.charAt(o1.length()-1)-o2.charAt(o2.length()-1);
			}
		});
		System.out.println(Arrays.toString(arr));
	}
}
class Student2{
	String name;
	int age;
	public Student2(String name, int age) {
		super();
		this.name = name;
		this.age = age;
	}
	@Override
	public String toString() {
		return "Student2 [name=" + name + ", age=" + age + "]";
	}
}
class Student1 implements Comparable<Student1>{
	String name;
	int age;
	public Student1(String name, int age) {
		super();
		this.name = name;
		this.age = age;
	}
	@Override
	public String toString() {
		return "Student [name=" + name + ", age=" + age + "]";
	}
  //2.完成Student类的自定义排序:
	@Override
	public int compareTo(Student1 o) {
		if(this.age==o.age) {
			//如果年龄相同的话,那么使用name的首字母升序
			return this.name.charAt(0)-o.name.charAt(0);
		}
		return o.age-this.age;
	}
}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
TreeMap是Java中的一种有序映射表,它可以根据键的自然顺序或者通过比较器进行排序。比较器是用来定义键的排序规则的对象。在TreeMap中,可以使用comparator()方法来获取当前使用的比较器对象。\[1\] 比较器可以通过覆写compare()方法来实现自定义的排序规则。例如,可以使用比较器对TreeMap中的键按照绝对值进行升序排序。\[2\]在这个例子中,使用了Lambda表达式来定义比较器,如果两个键的绝对值相等,则按照原始值进行排序。 如果TreeMap没有指定比较器,则会使用键的自然顺序进行排序。而comparator()方法则用于返回当前使用的比较器对象。如果TreeMap遵循默认排序规则,则comparator()方法将返回null。\[3\] #### 引用[.reference_title] - *1* *3* [treemap比较器_Java TreeMap比较器()方法与示例](https://blog.csdn.net/cumt951045/article/details/107765881)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control_2,239^v3^insert_chatgpt"}} ] [.reference_item] - *2* [比较器的初次尝试(二维数组比较器)+(TreeMap比较器:根据KEY的大小排列)+(优先队列)+(Map根据VALUE的...](https://blog.csdn.net/WC949464367/article/details/121941777)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control_2,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值