com.xenoamess.commons.primitive.comparators.DoubleComparator Maven / Gradle / Ivy
Show all versions of commonx Show documentation
package com.xenoamess.commons.primitive.comparators;
import com.xenoamess.commons.primitive.Primitive;
import java.util.*;
/**
* A comparison function, which imposes a total ordering on some
* collection of objects. Comparators can be passed to a sort method (such
* as {@link java.util.Collections#sort(List, Comparator) Collections.sort} or {@link
* Arrays#sort(Object[], Comparator) 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 {@link SortedSet sorted sets} or {@link
* SortedMap sorted maps}), or to provide an ordering for collections of
* objects that don't have a {@link Comparable natural ordering}.
*
* The ordering imposed by a comparator {@code c} on a set of elements
* {@code S} is said to be consistent with equals if and only if
* {@code c.compare(e1, e2)==0} has the same boolean value as
* {@code e1.equals(e2)} for every {@code e1} and {@code e2} in
* {@code S}.
*
* 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 {@code c}
* is used with elements (or keys) drawn from a set {@code S}. If the
* ordering imposed by {@code c} on {@code 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 {@code equals}.
*
* For example, suppose one adds two elements {@code a} and {@code b} such that
* {@code (a.equals(b) && c.compare(a, b) != 0)}
* to an empty {@code TreeSet} with comparator {@code c}.
* The second {@code add} operation will return
* true (and the size of the tree set will increase) because {@code a} and
* {@code b} are not equivalent from the tree set's perspective, even though
* this is contrary to the specification of the
* {@link java.util.Set#add Set.add} method.
*
* Note: It is generally a good idea for comparators to also implement
* {@code java.io.Serializable}, as they may be used as ordering methods in
* serializable data structures (like {@link java.util.TreeSet}, {@link java.util.TreeMap}). In
* order for the data structure to serialize successfully, the comparator (if
* provided) must implement {@code Serializable}.
*
* For the mathematically inclined, the relation that defines the
* imposed ordering that a given comparator {@code c} imposes on a
* given set of objects {@code S} is:
* {(x, y) such that c.compare(x, y) <= 0}.
*
The quotient for this total order is:
* {(x, y) such that c.compare(x, y) == 0}.
*
*
* It follows immediately from the contract for {@code compare} that the
* quotient is an equivalence relation on {@code S}, and that the
* imposed ordering is a total order on {@code S}. When we say that
* the ordering imposed by {@code c} on {@code S} is consistent with
* equals, we mean that the quotient for the ordering is the equivalence
* relation defined by the objects' {@link java.lang.Object#equals(Object)
* equals(Object)} method(s):
* {(x, y) such that x.equals(y)}.
*
* Unlike {@code 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.
*
* @author Josh Bloch
* @author Neal Gafter
* @author XenoAmess
* @version 0.6.0
* @see Comparable
* @see java.io.Serializable
* @see java.util.Comparator
* @since 1.2
*/
@FunctionalInterface
public interface DoubleComparator extends Comparator, Primitive {
/**
* {@inheritDoc}
*
* Compares its two arguments for order. Returns a negative integer,
* zero, or a positive integer as the first argument is less than, equal
* to, or greater than the second.
*
* The implementor must ensure that {@code sgn(compare(x, y)) ==
* -sgn(compare(y, x))} for all {@code x} and {@code y}. (This
* implies that {@code compare(x, y)} must throw an exception if and only
* if {@code compare(y, x)} throws an exception.)
*
* The implementor must also ensure that the relation is transitive:
* {@code ((compare(x, y)>0) && (compare(y, z)>0))} implies
* {@code compare(x, z)>0}.
*
* Finally, the implementor must ensure that {@code compare(x, y)==0}
* implies that {@code sgn(compare(x, z))==sgn(compare(y, z))} for all
* {@code z}.
*
* It is generally the case, but not strictly required that
* {@code (compare(x, y)==0) == (x.equals(y))}. Generally speaking,
* any comparator that violates this condition should clearly indicate
* this fact. The recommended language is "Note: this comparator
* imposes orderings that are inconsistent with equals."
*
* In the foregoing description, the notation
* {@code sgn(}expression{@code )} designates the mathematical
* signum function, which is defined to return one of {@code -1},
* {@code 0}, or {@code 1} according to whether the value of
* expression is negative, zero, or positive, respectively.
*/
@Override
default int compare(Double o1, Double o2) {
return comparePrimitive(o1, o2);
}
/**
* Primitive replacement of {@code DoubleComparator.compare(Double o1, Double o2)}
*
* @param p1 the first double to be compared.
* @param p2 the second double to be compared.
* @return a negative integer, zero, or a positive integer as the
* first argument is less than, equal to, or greater than the
* second.
* @see DoubleComparator#compare(Double o1, Double o2)
*/
int compare(double p1, double p2);
/**
* Primitive replacement of {@code DoubleComparator.compare(Double o1, Double o2)}
*
* @param p1 the first double to be compared.
* @param p2 the second double to be compared.
* @return a negative integer, zero, or a positive integer as the
* first argument is less than, equal to, or greater than the
* second.
* @see DoubleComparator#compare(Double o1, Double o2)
*/
default int comparePrimitive(double p1, double p2) {
return compare(p1, p2);
}
}