Java中如何使用 Comparator 和 Comparable?
Java 中的 Comparator
和 Comparable
之间的区别是非常流行的 Java 面试问题,主要在面试中被问到,而编写代码以使用 Comparable 或 Comparator 对对象进行排序在笔试面试中很流行。 问题是“你将如何根据 EmployeeID 和姓名对 Employee 对象进行排序”,这涉及到在 Java 中使用 Comparable 和 Comparator 接口。 这篇文章是我对 Java 基础知识的修订,类似于我对 Java 中的 equals
方法所做的修改,以及一些在 Java 中覆盖 hashCode
的技巧。
所有这些方法都是 Java 编程语言的基础,正确理解是任何 Java 开发人员都必须具备的。 Java中的 Comparators 和 Comparable 是Java中用来实现排序的两个接口。
经常需要对 ArrayList 、HashSet 或 Array 等任何集合类中存储的对象进行排序,这时我们需要使用 java.util.Comparator
和 java.lang.Comparable
中定义的 compare()
或 compareTo()
方法 .
在本 Java 文章中,我们将看到使用 Comparator 和 Comparable 对 Java 中的对象进行排序的示例,并讨论有关何时使用 Comparator 接口等的一些最佳实践。在继续之前的任何方式让我们看看 Java 中 Comparable 和 Comparator 之间的一些重要区别。
Java 中的 Comparator 与 Comparable
以下是一些常见的差异,如果在电话或面对面采访中被问到,请记住回答这个问题:
-
Java中的Comparator是在
java.util
包中定义的,而Java中的Comparable
接口是在java.lang
包中定义的,这非常说明 Comparator 应该用作对默认提供 Comparable 的对象进行排序的实用程序。 -
Java 中的比较器接口有方法
public int compare (Object o1, Object o2)
返回负整数、零或正整数,因为第一个参数小于、等于或大于第二个。 Comparable 接口的方法public int compareTo(Object o)
返回负整数、零或正整数,因为此对象小于、等于或大于指定对象。 -
如果你看到这两者之间的逻辑区别是Java中的 Comparator 比较提供给他的两个对象,而 Comparable 接口将
this
引用与指定的对象进行比较。 我分享了很多关于如何覆盖compareTo()
方法和避免程序员在实现 Comparable 接口时犯的一些常见错误的技巧。 -
Java中的 Comparable 用于实现对象的自然排序。 在 Java API String、Date 和包装类中实现了一个 Comparable 接口。为值对象覆盖
compareTo()
始终是一个好习惯。 -
如果任何类在 Java 中实现了 Comparable 接口,那么可以使用
Collections.sort()
或Arrays.sort()
方法自动对该对象的集合List
或Array
进行排序,并且对象将根据 CompareTo 定义的自然顺序进行排序 方法。 -
在Java中实现 Comparable 的对象可以用作 SortedMap(如TreeMap)中的键或 SortedSet(例如TreeSet)中的元素,而无需指定任何 Comparator。
这些是 Java 中 Comparator 和 Comparator 接口之间的一些理论和实践差异的组合。 它确实可以帮助我们决定何时使用 Comparator 与 Comparable,但是当我们围绕使用这两个接口进行一些最佳实践时,事情会变得更加清晰。 现在让我们看一个 Java 中比较器的例子:
Java中Comparator和Comparable的使用示例
所以总而言之,如果你想根据自然顺序对对象进行排序,那么在 Java 中使用 Comparable,如果你想根据对象的其他属性进行排序,那么在 Java 中使用 Comparator。 现在要了解这些概念,让我们看一个示例或现实生活中的编码:
-
有一个类叫Person,根据person_id对Person进行排序,person_id是数据库中的主键
-
根据名字对人进行排序。
对于一个 Person
类,基于 person_id 的排序可以看作自然顺序排序,基于name字段的排序可以使用 Comparator 接口来实现。 要根据 person_id 进行排序,我们需要实现 compareTo()
方法。
public class Person implements Comparable {
private int person_id;
private String name;
/**
* 将当前人与指定人进行比较
* 如果两个人的 person_id 相同则返回零
* 如果当前 person_id 小于指定一则返回负
* 如果指定 person_id 大于指定一则返回正
*/
@Override
public int compareTo(Object o) {
Person p = (Person) o;
return this.person_id - o.person_id ;
}
….
}
通常,我们不应该使用整数的差异来决定 compareTo
方法的输出,因为整数减法的结果可能会溢出,但如果我们确定两个操作数都是正数,那么它是比较两个对象的最快方法之一。
对于基于人名的排序,我们可以实现 Java Comparator 类的 compare(Object o1, Object o2)
方法。
public class SortByPerson_ID implements Comparator{
public int compare(Object o1, Object o2) {
Person p1 = (Person) o;
Person p2 = (Person) o;
return p1.getPersonId() - p2.getPersonId();
}
}
类似的准则也适用于实现 compare()
方法,而不是使用减法运算符,最好使用逻辑运算符来比较两个整数是否等于、小于或大于。 我们可以根据需要编写多种类型的 Java Comparator,例如 reverseComparator
、 ANDComparator
、 ORComparator
等,它们将根据逻辑结果返回负数或正数。 Java 中的 String 甚至提供了一个特殊的比较器,称为 CASE_INSENSITIVE_ORDER
,用于对 String 对象执行不区分大小写的比较。
如何在 Java 中比较字符串
字符串在 Java 中是不可变的,是最常用的值类之一。 对于在 Java 中比较 String 我们不应该担心,因为 String 实现了 Comparable
接口并为 CompareTo
方法提供了字典顺序实现,该方法根据字符的内容比较两个字符串,或者您可以按词汇顺序说。 我们只需要调用 String.compareTo(AnotherString)
,Java 将确定指定的字符串是否大于、等于或小于当前对象。
如何在 Java 中比较日期
日期在 Java 中由 java.util.Date
类表示,与 String 一样,Date 在 Java 中也实现了 Comparable,因此如果它们存储在任何已排序的集合(如 TreeSet 或 TreeMap)中,它们将根据其自然顺序自动排序。 如果您明确想要在 Java 中比较两个日期,您可以在 Java 中调用 Date.compareTo(AnotherDate)
方法,它会告诉我们指定的日期是大于、等于还是小于当前字符串。
何时在 Java 中使用 Comparator 和 Comparable
最后让我们看看关于何时在 Java 中使用 Comparator 或 Comparable 的一些最佳实践和建议:
1) 如果在 Class 的开发过程中已经存在自然或默认的排序对象的方式,则使用 Comparable
。 这是直观的,你得到的类名人们应该能够正确猜出它,就像字符串是长期排序的,Employee 可以按他们的 Id 等排序。
另一方面,如果可以通过多种方式对对象进行排序,并且客户端正在指定应该对哪个参数进行排序,则使用 Comparator
接口。 例如,Employee 可以再次按姓名、薪水或部门排序,客户需要一个 API 来执行此操作。 比较器实现可以解决这个问题。
2) 有时我们编写代码来对您不是原始作者的类的对象进行排序,或者您无权访问代码。 在这些情况下,我们无法实现 Comparable
,而 Comparator 是对这些对象进行排序的唯一方法。
3) 注意这些对象如果像 TreeSet 和 TreeMap 一样存储在 SorteSet 或 SortedMap 中将如何表现。 如果一个对象没有实现 Comparable,那么在将它们放入 SortedMap 时,总是提供一个相应的 Comparator,它可以提供排序逻辑。
4) 在实现 Comparable
或 Comparator
接口时,比较顺序非常重要。 例如,如果我们根据姓名对对象进行排序,那么我们可以按任何顺序比较名字或姓氏,因此请明智地决定。
5) Comparator 具有自我描述的明显优势,例如,如果我们正在编写 Comparator 来根据他们的薪水比较两个 Employees,那么将比较器命名为 SalaryComparator,另一方面,compareTo()
相关文章
在 Java 中获取文件大小
发布时间:2023/05/01 浏览次数:139 分类:Java
-
Java 提供了不同的方法来获取文件的字节大小。 本教程演示了在 Java 中获取文件大小的不同方法。使用 Java IO 的文件类获取文件大小 Java IO 包的 File 类提供了以字节为单位获取文件大小的功能。
Java 中的文件分隔符
发布时间:2023/05/01 浏览次数:108 分类:Java
-
本篇文章介绍了 Java 中的文件分隔符。Java 中的文件分隔符 文件分隔符是用来分隔目录的字符; 例如,Unix 使用 /,Windows 使用 \ 作为文件分隔符。
Java 中的文件过滤器
发布时间:2023/05/01 浏览次数:193 分类:Java
-
本篇文章介绍如何在 Java 中使用 FileFilter。FileFilter 用于过滤具有特定扩展名的文件。 Java内置包IO和Apache Commons IO为FileFilter提供了类和接口来进行文件过滤操作。
Java 获取 ISO 8601 格式的当前时间戳
发布时间:2023/05/01 浏览次数:132 分类:Java
-
本篇文章介绍了 ISO 8601 日期格式、其重要性及其在 Java 中的使用。 它还列出了一些优点来强调为什么应该使用 ISO 格式来表示日期。
在 Java 中获取数组的子集
发布时间:2023/05/01 浏览次数:142 分类:Java
-
本篇文章介绍了几种在 Java 中获取数组子集的方法。使用 Arrays.copyOf() 方法获取数组的子集 使用 Arrays.copyOfRange() 方法获取数组的子集
用 Java 填充二维数组
发布时间:2023/05/01 浏览次数:110 分类:Java
-
二维数组是基于表结构的,即行和列,填充二维数组不能通过简单的添加到数组操作来完成。 本篇文章介绍如何在 Java 中填充二维数组。
计算 Java 数组中的重复元素
发布时间:2023/05/01 浏览次数:202 分类:Java
-
本篇文章介绍Java计算数组中重复元素的方法。计算 Java 数组中的重复元素。我们可以创建一个程序来计算数组中的重复元素。 该数组可以是未排序的,也可以是已排序的。
Java 中 List 和 Arraylist 的区别
发布时间:2023/05/01 浏览次数:90 分类:Java
-
表示为单个单元的一组单个对象称为集合。 在 Java 中,Collection 是一个具有多个已定义接口和类的框架,用于将一组对象表示为一个单元。 它允许我们操纵