工具类-比较器Comparable和Comparator

前言:

  • 对于一些数据需要按规则进行排序存取到集合中,所以我们需要进行冒泡排序或者快速排序,JDK提供了比较器的接口,我们只关注数据的排序规则,而不需关注存储过程。
  • 使用JDK提供的排序器,我们可以配合java.util包的类进行使用,如Arrays类、TreeSet

Comparable

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.

该接口对实现它的每个类的对象强加了总排序。这种排序称为类的自然排序,类的 compareTo 方法称为其自然比较方法。

Lists (and arrays) of objects that implement this interface can be sorted automatically by Collections.sort (and Arrays.sort). Objects that implement this interface can be used as keys in a sorted map or as elements in a sorted set, without the need to specify a comparator.

实现此接口的对象列表(和数组)可以通过 Collections.sort(和 Arrays.sort)自动排序。实现此接口的对象可以用作排序映射中的键或排序集中的元素,而无需指定比较器。

The natural ordering for a class C is said to be consistent with equals if and only if e1.compareTo(e2) == 0 has the same boolean value as e1.equals(e2) for every e1 and e2 of class C. Note that null is not an instance of any class, and e.compareTo(null) should throw a NullPointerException even though e.equals(null) returns false.

当且仅当 e1.compareTo(e2) == 0 对于类 C 的每个 e1 和 e2 具有与 e1.equals(e2) 相同的布尔值时,才说类 C 的自然顺序与 equals 一致。请注意, null 不是任何类的实例,即使 e.equals(null) 返回 false,e.compareTo(null) 也应该抛出 NullPointerException。

It is strongly recommended (though not required) that natural orderings be consistent with equals. This is so because sorted sets (and sorted maps) without explicit comparators behave “strangely” when they are used with elements (or keys) whose natural ordering is inconsistent with equals. In particular, such a sorted set (or sorted map) violates the general contract for set (or map), which is defined in terms of the equals method.

强烈建议(虽然不是必需的)自然顺序与 equals 一致。之所以如此,是因为没有显式比较器的排序集(和排序映射)在与自然顺序与 equals 不一致的元素(或键)一起使用时表现得“奇怪”。特别是,这样的排序集合(或排序映射)违反了集合(或映射)的一般契约,它是根据 equals 方法定义的。

For example, if one adds two keys a and b such that (!a.equals(b) && a.compareTo(b) == 0) to a sorted set that does not use an explicit comparator, the second add operation returns false (and the size of the sorted set does not increase) because a and b are equivalent from the sorted set’s perspective.

例如,如果将两个键 a 和 b 相加使得 (!a.equals(b) && a.compareTo(b) == 0) 到一个不使用显式比较器的有序集合,则第二个加法操作返回 false (并且排序集的大小不会增加)因为从排序集的角度来看 a 和 b 是等效的。

Virtually all Java core classes that implement Comparable have natural orderings that are consistent with equals. One exception is java.math.BigDecimal, whose natural ordering equates BigDecimal objects with equal values and different precisions (such as 4.0 and 4.00).

几乎所有实现 Comparable 的 Java 核心类都具有与 equals 一致的自然顺序。一个例外是 java.math.BigDecimal,它的自然排序将 BigDecimal 对象等同于具有相同的值和不同的精度(例如 4.0 和 4.00)。

For the mathematically inclined, the relation that defines the natural ordering on a given class C is:
{(x, y) such that x.compareTo(y) <= 0}.

对于数学倾向,定义给定类 C 的自然排序的关系是:
{(x, y) 使得 x.compareTo(y) <= 0}。

The quotient for this total order is:
{(x, y) such that x.compareTo(y) == 0}.

这个总订单的商是:
{(x, y) 使得 x.compareTo(y) == 0}。

It follows immediately from the contract for compareTo that the quotient is an equivalence relation on C, and that the natural ordering is a total order on C. When we say that a class’s natural ordering is consistent with equals, we mean that the quotient for the natural ordering is the equivalence relation defined by the class’s equals(Object) method:
{(x, y) such that x.equals(y)}.
This interface is a member of the Java Collections Framework.
Compares this

从compareTo 的契约可以直接得出商是C 上的等价关系,并且自然排序是C 上的全序。当我们说一个类的自然排序与equals 一致时,我们的意思是自然排序是由类的 equals(Object) 方法定义的等价关系:
{(x, y) 使得 x.equals(y)}。
此接口是 Java 集合框架的成员。

public int compareTo(T o);

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.

将此对象与指定的对象进行比较以进行排序。当此对象小于、等于或大于指定对象时,返回一个负整数、零或正整数。

The implementor must ensure sgn(x.compareTo(y)) == -sgn(y.compareTo(x)) for all x and y. (This implies that x.compareTo(y) must throw an exception iff y.compareTo(x) throws an exception.)

实现者必须确保所有 x 和 y 的 sgn(x.compareTo(y)) == -sgn(y.compareTo(x))。 (这意味着 x.compareTo(y) 必须抛出异常,如果 y.compareTo(x) 抛出异常。)

The implementor must also ensure that the relation is transitive: (x.compareTo(y)>0 && y.compareTo(z)>0) implies x.compareTo(z)>0.

实现者还必须确保关系是可传递的:(x.compareTo(y)>0 && y.compareTo(z)>0) 意味着 x.compareTo(z)>0。

Finally, the implementor must ensure that x.compareTo(y)==0 implies that sgn(x.compareTo(z)) == sgn(y.compareTo(z)), for all z.

最后,实现者必须确保 x.compareTo(y)==0 意味着 sgn(x.compareTo(z)) == sgn(y.compareTo(z)),对于所有 z。

It is strongly recommended, but not strictly required that (x.compareTo(y)==0) == (x.equals(y)). Generally speaking, any class that implements the Comparable interface and violates this condition should clearly indicate this fact. The recommended language is “Note: this class has a natural ordering that is inconsistent with equals.”

强烈推荐,但不严格要求 (x.compareTo(y)==0) == (x.equals(y))。一般来说,任何实现 Comparable 接口并违反此条件的类都应该清楚地表明这一事实。推荐的语言是“注意:这个类有一个与 equals 不一致的自然顺序。”

In the foregoing description, the notation sgn(expression) designates the mathematical signum function, which is defined to return one of -1, 0, or 1 according to whether the value of expression is negative, zero or positive.

在前面的描述中,符号sgn(expression)表示数学符号函数,其被定义为根据表达式的值是负、零还是正来返回-1、0或1之一。

Comparator

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.

一个比较函数,它对某些对象集合进行总排序。比较器可以传递给排序方法(例如 Collections.sort 或 Arrays.sort)以允许精确控制排序顺序。比较器还可用于控制某些数据结构(例如排序集或排序映射)的顺序,或为没有自然排序的对象集合提供排序。

The ordering imposed by a comparator c on a set of elements S is said to be consistent with equals if and only if c.compare(e1, e2)==0 has the same boolean value as e1.equals(e2) for every e1 and e2 in S.

当且仅当 c.compare(e1, e2)==0 与 e1.equals(e2) 对于每个 e1 具有相同的布尔值时,比较器 c 对一组元素 S 施加的排序称为与等于一致和 S 中的 e2。

Caution should be exercised when using a comparator capable of imposing an ordering inconsistent with equals to order a sorted set (or sorted map). Suppose a sorted set (or sorted map) with an explicit comparator c is used with elements (or keys) drawn from a set S. If the ordering imposed by c on S is inconsistent with equals, the sorted set (or sorted map) will behave “strangely.” In particular the sorted set (or sorted map) will violate the general contract for set (or map), which is defined in terms of equals.

当使用能够强加与等于不一致的排序的比较器对已排序集合(或已排序映射)进行排序时,应谨慎行事。假设一个带有显式比较器 c 的排序集合(或排序映射)与从集合 S 中提取的元素(或键)一起使用。如果 c 对 S 施加的排序与等于不一致,则排序集合(或排序映射)将表现得“奇怪”。特别是排序集合(或排序映射)将违反集合(或映射)的一般契约,它是根据等号定义的。

For example, suppose one adds two elements a and b such that (a.equals(b) && c.compare(a, b) != 0) to an empty TreeSet with comparator c. The second add operation will return true (and the size of the tree set will increase) because a and b are not equivalent from the tree set’s perspective, even though this is contrary to the specification of the Set.add method.

例如,假设将两个元素 a 和 b 相加,使得 (a.equals(b) && c.compare(a, b) != 0) 到一个带有比较器 c 的空 TreeSet。第二个 add 操作将返回 true(并且树集的大小会增加),因为从树集的角度来看 a 和 b 并不等效,即使这与 Set.add 方法的规范相悖。

Note: It is generally a good idea for comparators to also implement java.io.Serializable, as they may be used as ordering methods in serializable data structures (like TreeSet, TreeMap). In order for the data structure to serialize successfully, the comparator (if provided) must implement Serializable.

注意:比较器也实现 java.io.Serializable 通常是个好主意,因为它们可以用作可序列化数据结构(如 TreeSet、TreeMap)中的排序方法。为了使数据结构成功序列化,比较器(如果提供)必须实现 Serializable。

For the mathematically inclined, the relation that defines the imposed ordering that a given comparator c imposes on a given set of objects S is:
{(x, y) such that c.compare(x, y) <= 0}.

对于数学倾向,定义给定比较器 c 强加给给定对象集 S 的强加排序的关系是:
{(x, y) 使得 c.compare(x, y) <= 0}。

The quotient for this total order is:
{(x, y) such that c.compare(x, y) == 0}.

这个总订单的商是:
{(x, y) 使得 c.compare(x, y) == 0}。

It follows immediately from the contract for compare that the quotient is an equivalence relation on S, and that the imposed ordering is a total order on S. When we say that the ordering imposed by c on S is consistent with equals, we mean that the quotient for the ordering is the equivalence relation defined by the objects’ equals(Object) method(s):
{(x, y) such that x.equals(y)}.

由比较契约直接推导出商是 S 上的等价关系,并且强加的排序是 S 上的全序。排序的商是由对象的 equals(Object) 方法定义的等价关系:
{(x, y) 使得 x.equals(y)}。

Unlike Comparable, a comparator may optionally permit comparison of null arguments, while maintaining the requirements for an equivalence relation.
This interface is a member of the Java Collections Framework.

与 Comparable 不同,比较器可以选择允许比较空参数,同时保持对等价关系的要求。
此接口是 Java 集合框架的成员。

总体对比

  • Comparable判断null会空指针,而Comparator可以对null进行判断
  • Comparable自然排序只有一种排序规则,而Comparator比较器可以有多重排序器
  • Comparable与Comparator同时出现,优先使用Comparator比较器的规则
  • 两者都是函数式接口,可以用Lambda方式解耦实现方法
上一篇:【Web】 通过浏览器打开本地应用程序


下一篇:命令行操作