关于Java中Comparable 和 Comparator的用法

Comparable 和 Comparator

Comparable 和 Comparator 是Java的两个和排序相关的接口,又被称为 自然排序和定制排序。最近看了相关的内容,现在来记录以下自己的学习情况。
Comparable 和 Comparator 是关于排序的两个接口,用来实现 Java 集合中的的排序功能。具体作用可以查看 API 获取。

Comparable

这是API 文档中的简要介绍:

This interface imposes a total ordering on the objects of each class that implements it. This ordering is referred to as the class’s natural ordering, and the class’s compareTo method is referred to as its natural comparison method. Compares this object with the specified object for order. Returns a negative integer, zero, or a positive integer as this object is less than, equal to, or greater than the specified object.

用法:

需要排序实体类的实现 Comparable 接口,并重写 compareTo() 方法,就可以具有排序功能。某些会自动对元素进行排序的集合(如 TreeSet),当把元素放入集合中,就会自动调用 CompareTo() 方法进行排序(前提是元素必须实现这个接口)。但是其他的地方也可以使用的,不只是局限于 TreeSet,使用还是很广泛的。

Comparator

这是API 文档中的简要介绍:

A comparison function, which imposes a total ordering on some collection of objects. Comparators can be passed to a sort method (such as Collections.sort or Arrays.sort) to allow precise control over the sort order. Comparators can also be used to control the order of certain data structures (such as sorted sets or sorted maps), or to provide an ordering for collections of objects that don’t have a natural ordering.

用法:

Comparator 是一个第三方接口,具体用法是:设计一个比较器,创建一个类,实现这个接口,重写 compare() 方法。并且由于 Comparator 是一个函数式接口,可以使用 Lambda 表达式代替 Comparator 对象,使得代码更加简洁明了。

Talk is cheap, show me the code.

注意:博客中的内容可能不会很详细,所以想看的具体细节的,应该以书本和官方文档为主,这里的内容更多的是简单的介绍一下基本的用法。

测试实体类:Dog

public class Dog implements Comparable<Dog>{
	private String name;
	private int age;

	public Dog(String name, int age) {
		this.name = name;
		this.age = 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;
	}

	@Override
	public String toString() {
		return "Dog [name=" + name + ", age=" + age + "]";
	}

	@Override
	public int compareTo(Dog dog) {
		return this.age > dog.age ? 1 : this.age < dog.age ? -1 : 0;
	}
}

测试实体类:Cat

public class Cat implements Comparable<Cat>{
	private String name;
	private Integer age;

	public Cat(String name, Integer age) {
		this.name = name;
		this.age = age;
	}

	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public Integer getAge() {
		return age;
	}
	public void setAge(Integer age) {
		this.age = age;
	}

	@Override
	public String toString() {
		return "Cat [name=" + name + ", age=" + age + "]";
	}

	@Override
	public int compareTo(Cat o) {
		//可以直接调用,这样更简单
		//调换 o.age 和 this.age 就是相反的顺序
		return o.age.compareTo(this.age);
	}
}

测试类:Test

public class Test {
	public static void main(String[] args) {
		List<Dog> dogs = new LinkedList<>();
		List<Cat> cats = new LinkedList<>();

		dogs.add(new Dog("大黄",6));
		dogs.add(new Dog("大白",1));
		dogs.add(new Dog("小黑",5));
		dogs.add(new Dog("旺财",3));
		dogs.add(new Dog("二哈",2));

		cats.add(new Cat("牛牛",3));
		cats.add(new Cat("花咪",4));
		cats.add(new Cat("咪咪",10));
		cats.add(new Cat("小黄",2));
		cats.add(new Cat("大橘",6));

		//参数为 null 使用 自然排序,否则使用 定制排序
		//也可以看出来 定制排序 优先级高于 自然排序
		System.out.println("---------自然排序 升序--------");
		dogs.sort(null);
		dogs.forEach(System.out::println);
		System.out.println("---------自然排序 降序--------");
		cats.sort(null);
		cats.forEach(System.out::println);

		//定制排序
	    //Comparator<Dog> c = (e1,e2)->e2.getAge() - e1.getAge();
		//dogs.sort(c) 这个就是下面这个的具体形式,
		//可以看出来参数是一个 Comparator 对象
		System.out.println("---------定制排序 降序--------");
		dogs.sort((e1,e2)->e2.getAge() - e1.getAge());
		//流式API的简单的应用,效果和上面的类似,或者直接使用 forEacn 循环遍历
		dogs.stream().forEach(System.out::println);
		System.out.println("---------定制排序 升序--------");
	//	另一种遍历方式,可以看出来函数式编程非常灵活,我也是初学,觉得很神奇。
		cats.stream()
		.sorted((e1,e2)->e1.getAge()-e2.getAge())
		.forEach(System.out::println);
	}
}

运行截图:

补充说明:list.sort()方法
API 文档中的描述:

Sorts this list according to the order induced by the specified Comparator.
All elements in this list must be mutually comparable using the specified comparator (that is, c.compare(e1, e2) must not throw a ClassCastException for any elements e1 and e2 in the list). If the specified comparator is null then all elements in this list must implement the Comparable interface and the elements’s natural ordering should be used. This list must be modifiable, but need not be resizable.

可以看到,这个方法进行排序通过一个 Comparator 对象,如果传入参数为 null 的话,则会进行自然排序,但是注意:自然排序的前提是相应的实体类实现了 Comparable 接口,并重写了 compareTo() 方法。

总结

简单了解了一下 Comparable 和 Comparator 接口的作用和简单的使用方法,这里使用了一点 Lambda 表达式的知识,不过都只是很浅显的知识,应该不难理解(我也只是正在学习中,哈哈)。通过一个 Dog 类和 Cat 类进行讲解,我觉得很好,首先它很容易理解,并且可以快速掌握简单的使用方法(学习是渐进式的,要一直努力学习知识才行)。

到此这篇关于关于Java中Comparable 和 Comparator的用法的文章就介绍到这了,更多相关Comparable和Comparator的用法内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • Java元素排序Comparable与Comparator的区别

    目录 1.字面含义不同 2.用法不同 2.1 Comparable 2.2 compareTo 排序方法说明 2.3 Comparator 3.扩展:Comparator 匿名类 4.使用的场景不同 总结 两者比较结构图: 在 Java 语言中,Comparable 和 Comparator 都是用来进行元素排序的,但二者有着本质的区别.它们两也是常见的面试题,所以今天我们一起来盘它. 1.字面含义不同 我们先从二者的字面含义来理解它,Comparable 翻译为中文是“比较”的意思,而 Com

  • 深入分析Comparable与Comparator及Clonable三个Java接口

    目录 1.Comparable 2.Comparator比较器 3.Clonable接口和深拷贝 1.Comparable 这个接口是用来给对象数组来排序的 在我学接口之前我用的排序方法是Arrays.sort(),我发现单单靠之前所学知识并不能解决给对象数组排序的问题,后来学习过程中发现Comparable这一接口解决了我的疑惑,也感受到了这一接口的强大之处,但这也不是最好的,后续会说到,毕竟学知识是个循序渐进的过程嘛 首先,我们看一下我们之前学习时用的Arrays.sort public c

  • Java中的Comparable和Comparator接口

    目录 一. Comparable接口 1. Comparable简介 2. 为什么要实现Comparable接口 3. Comparable的实际应用 二. Comparator接口 1. Comparator简介 2. Comparator接口的实际运用 三. Comparable和Comparator的比较 一. Comparable接口 1. Comparable简介 Comparable是排序接口. 若一个类实现了Comparable接口,就意味着该类支持排序. 实现了Comparabl

  • Java的Comparable,Comparator和Cloneable三大接口详解

    目录 1.比较器 1.1Comparable接口 1.2Comparator接口 2.Cloneable接口 2.1深拷贝和浅拷贝 总结 1.比较器 ①比较器的引入 a.首先,当我们单一地比较某一种数据类型的数组时,可以直接用Arrays.sort()进行实现 b.而当我们同时含有多个参数时,并没有告诉我们按照什么来进行排序,此时,若是用Arrays.sort()就会出现报错的情况  基于这种情况,我们了解到,若是要将自定义类型进行大小比较 ,就要引入能够实现比较的接口,下面我们介绍Compar

  • java 集合工具类Collections及Comparable和Comparator排序详解

    目录 一.常用功能 二.Comparator比较器 三.Comparable和Comparator两个接口的区别 四.练习 五.扩展 一.常用功能 java.utils.Collections是集合工具类,用来对集合进行操作. 部分方法如下: public static <T> boolean addAll(Collection<T> c, T... elements):往集合中添加一些元素. public static void shuffle(List<?> lis

  • java 中Comparable与Comparator详解与比较

    java 中Comparable与Comparator详解 今天查看TreeMap的源码,发现其键必须是实现Comparable或者Comparator的接口时产生了一些兴趣,比如在TreeMap中的put方法分别对Comparable和Comparator接口分别进行处理.那么疑问就来了,Comparable和Comparator接口的区别是什么,Java中为什么会存在两个类似的接口?   Comparable和Comparator接口都是用来比较大小的,首先来看一下Comparable的定义

  • 详解Java中Comparable和Comparator接口的区别

    详解Java中Comparable和Comparator接口的区别 本文要来详细分析一下Java中Comparable和Comparator接口的区别,两者都有比较的功能,那么究竟有什么区别呢,感兴趣的Java开发者继续看下去吧. Comparable 简介 Comparable 是排序接口. 若一个类实现了Comparable接口,就意味着"该类支持排序".  即然实现Comparable接口的类支持排序,假设现在存在"实现Comparable接口的类的对象的List列表(

  • Java 中Comparable和Comparator区别比较

    Comparable 简介Comparable 是排序接口.若一个类实现了Comparable接口,就意味着"该类支持排序".  即然实现Comparable接口的类支持排序,假设现在存在"实现Comparable接口的类的对象的List列表(或数组)",则该List列表(或数组)可以通过 Collections.sort(或 Arrays.sort)进行排序.此外,"实现Comparable接口的类的对象"可以用作"有序映射(如Tre

  • java中的内部类内部接口用法说明

    简介 一般来说,我们创建类和接口的时候都是一个类一个文件,一个接口一个文件,但有时候为了方便或者某些特殊的原因,java并不介意在一个文件中写多个类和多个接口,这就有了我们今天要讲的内部类和内部接口. 内部类 先讲内部类,内部类就是在类中定义的类.类中的类可以看做是类的一个属性,一个属性可以是static也可以是非static的.而内部类也可以定义在类的方法中,再加上匿名类,总共有5种内部类. 静态内部类 我们在class内部定义一个static的class,如下所示: @Slf4j publi

  • JAVA中Comparable接口和自定义比较器示例讲解

    自然排序 TreeSet集合在存储数据时有一定的顺序,它会将一些数据进行比较,比较调用的是comparaTo()方法,该方法是在Comparable中定义的,自然排序要求TreeSet集合中存储的数据必须实现Comparable接口,并且重写ComparaTo()方法 public class 自然排序 { public static void main(String[] args) { //定义一个TreeSet集合 TreeSet treeSet = new TreeSet(); Teach

  • 详解Java中String类的各种用法

    目录 一.创建字符串 二.字符.字节与字符串的转换 1.字符与字符串的转换 2.字节与字符串的转换 三.字符串的比较 1.字符串常量池 2.字符串内容比较 四.字符串查找 五.字符串替换 六.字符串拆分 七.字符串截取 八.String类中其它的常用方法 九.StringBuffer 和 StringBuilder 1.StringBuilder与StringBuffer的区别 2.StringBuilder与StringBuffer常用的方法 十.对字符串引用的理解 一.创建字符串 创建字符串

  • Java中的接口和抽象类用法实例详解

    本文实例讲述了Java中的接口和抽象类用法.分享给大家供大家参考,具体如下: 在面向对象的概念中,我们知道所有的对象都是通过类来描绘的,但是并不是所有的类都是用来描绘对象的,如果一个类中没有包含足够的信息来描绘一个具体的对象,这样的类就是抽象类. 抽象类往往用来表征我们在对问题领域进行分析. 设计中得出的抽象概念,是对一系列看上去不同,但是本质上相同的具体概念的抽象,我们不能把它们实例化(拿不出一个具体的东西)所以称之为抽象. 比如:我们要描述"水果",它就是一个抽象,它有质量.体积等

  • Java中BigDecimal类的简单用法

    本文实例讲述了Java中BigDecimal类的简单用法,是Java程序设计中非常实用的技巧,分享给大家供大家参考.具体用法分析如下: 一般来说,一提到Java里面的商业计算,我们都知道不能用float和double,因为他们无法进行精确计算.但是Java的设计者给编程人员提供了一个很有用的类BigDecimal,他可以完善float和double类无法进行精确计算的缺憾.BigDecimal类位于java.maths类包下.首先我们来看下如何构造一个BigDecimal对象.它的构造函数很多,

  • Java中汉字转拼音pinyin4j用法实例分析

    本文实例讲述了Java中汉字转拼音pinyin4j用法.分享给大家供大家参考,具体如下: 汉字转换拼音在日常开发中是个很常见的问题.例如我们伟大的12306,在地名中输入"WH",就会出现"武汉""芜湖""威海"等地名,输入"WUHU"就会出现"芜湖". Java获取汉字的拼音,pinyin4j这个库可以很好的解决这个问题. 下载地址:http://sourceforge.net/pro

  • 浅谈java中==以及equals方法的用法

    equals 方法是 java.lang.Object 类的方法. 有两种用法说明: (1)对于字符串变量来说,使用"=="和"equals()"方法比较字符串时,其比较方法不同. "=="比较两个变量本身的值,即两个对象在内存中的首地址. "equals()"比较字符串中所包含的内容是否相同. 比如: String s1,s2,s3 = "abc", s4 ="abc" ; s1 =

随机推荐