github.com/searKing/golang/go@v1.2.74/util/comparator.go (about)

     1  // Copyright 2020 The searKing Author. All rights reserved.
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  
     5  package util
     6  
     7  import (
     8  	"github.com/searKing/golang/go/util/object"
     9  )
    10  
    11  type Comparator interface {
    12  	/**
    13  	 * Compares its two arguments for order.  Returns a negative integer,
    14  	 * zero, or a positive integer as the first argument is less than, equal
    15  	 * to, or greater than the second.<p>
    16  	 *
    17  	 * The implementor must ensure that {@code sgn(compare(x, y)) ==
    18  	 * -sgn(compare(y, x))} for all {@code x} and {@code y}.  (This
    19  	 * implies that {@code compare(x, y)} must throw an exception if and only
    20  	 * if {@code compare(y, x)} throws an exception.)<p>
    21  	 *
    22  	 * The implementor must also ensure that the relation is transitive:
    23  	 * {@code ((compare(x, y)>0) && (compare(y, z)>0))} implies
    24  	 * {@code compare(x, z)>0}.<p>
    25  	 *
    26  	 * Finally, the implementor must ensure that {@code compare(x, y)==0}
    27  	 * implies that {@code sgn(compare(x, z))==sgn(compare(y, z))} for all
    28  	 * {@code z}.<p>
    29  	 *
    30  	 * It is generally the case, but <i>not</i> strictly required that
    31  	 * {@code (compare(x, y)==0) == (x.equals(y))}.  Generally speaking,
    32  	 * any comparator that violates this condition should clearly indicate
    33  	 * this fact.  The recommended language is "Note: this comparator
    34  	 * imposes orderings that are inconsistent with equals."<p>
    35  	 *
    36  	 * In the foregoing description, the notation
    37  	 * {@code sgn(}<i>expression</i>{@code )} designates the mathematical
    38  	 * <i>signum</i> function, which is defined to return one of {@code -1},
    39  	 * {@code 0}, or {@code 1} according to whether the value of
    40  	 * <i>expression</i> is negative, zero, or positive, respectively.
    41  	 *
    42  	 * @param o1 the first object to be compared.
    43  	 * @param o2 the second object to be compared.
    44  	 * @return a negative integer, zero, or a positive integer as the
    45  	 *         first argument is less than, equal to, or greater than the
    46  	 *         second.
    47  	 * @throws NullPointerException if an argument is null and this
    48  	 *         comparator does not permit null arguments
    49  	 * @throws ClassCastException if the arguments' types prevent them from
    50  	 *         being compared by this comparator.
    51  	 */
    52  	Compare(a, b interface{}) int
    53  	/**
    54  	 * Returns a lexicographic-order comparator with another comparator.
    55  	 * If this {@code Comparator} considers two elements equal, i.e.
    56  	 * {@code compare(a, b) == 0}, {@code other} is used to determine the order.
    57  	 *
    58  	 * <p>The returned comparator is serializable if the specified comparator
    59  	 * is also serializable.
    60  	 *
    61  	 * @apiNote
    62  	 * For example, to sort a collection of {@code String} based on the length
    63  	 * and then case-insensitive natural ordering, the comparator can be
    64  	 * composed using following code,
    65  	 *
    66  	 * <pre>{@code
    67  	 *     Comparator<String> cmp = Comparator.comparingInt(String::length)
    68  	 *             .thenComparing(String.CASE_INSENSITIVE_ORDER);
    69  	 * }</pre>
    70  	 *
    71  	 * @param  other the other comparator to be used when this comparator
    72  	 *         compares two objects that are equal.
    73  	 * @return a lexicographic-order comparator composed of this and then the
    74  	 *         other comparator
    75  	 * @throws NullPointerException if the argument is null.
    76  	 * @since 1.8
    77  	 */
    78  	ThenComparing(after Comparator) Comparator
    79  
    80  	Reversed() Comparator
    81  }
    82  
    83  // The HandlerFunc type is an adapter to allow the use of
    84  // ordinary functions as HTTP handlers. If f is a function
    85  // with the appropriate signature, HandlerFunc(f) is a
    86  // Handler that calls f.
    87  type ComparatorFunc func(a, b interface{}) int
    88  
    89  // Compare calls f(a,b).
    90  func (f ComparatorFunc) Compare(a, b interface{}) int {
    91  	return f(a, b)
    92  }
    93  
    94  func (f ComparatorFunc) Reversed() Comparator {
    95  	return ComparatorFunc(func(a, b interface{}) int {
    96  		return f.Compare(b, a)
    97  	})
    98  }
    99  
   100  func (f ComparatorFunc) ThenComparing(after Comparator) Comparator {
   101  	object.RequireNonNil(after)
   102  	return ComparatorFunc(func(a, b interface{}) int {
   103  		res := f.Compare(a, b)
   104  		if res != 0 {
   105  			return res
   106  		}
   107  		return after.Compare(a, b)
   108  	})
   109  }
   110  
   111  /**
   112   * Returns a null-friendly comparator that considers {@code null} to be
   113   * less than non-null. When both are {@code null}, they are considered
   114   * equal. If both are non-null, the specified {@code Comparator} is used
   115   * to determine the order. If the specified comparator is {@code null},
   116   * then the returned comparator considers all non-null values to be equal.
   117   *
   118   * <p>The returned comparator is serializable if the specified comparator
   119   * is serializable.
   120   *
   121   * @param  <T> the type of the elements to be compared
   122   * @param  comparator a {@code Comparator} for comparing non-null values
   123   * @return a comparator that considers {@code null} to be less than
   124   *         non-null, and compares non-null objects with the supplied
   125   *         {@code Comparator}.
   126   * @since 1.8
   127   */
   128  func NullFirst(cmp Comparator, nilFirst bool) Comparator {
   129  	return NewNullComparator(nilFirst, cmp)
   130  }
   131  
   132  // DefaultComparator returns 0 if a == b, returns -1 otherwise
   133  func DefaultComparator() Comparator {
   134  	return ComparatorFunc(func(a, b interface{}) int {
   135  		if a == b {
   136  			return 0
   137  		}
   138  		return -1
   139  	})
   140  }
   141  
   142  // AlwaysEqualComparator returns 0 always
   143  func AlwaysEqualComparator() Comparator {
   144  	return ComparatorFunc(func(_, _ interface{}) int {
   145  		return 0
   146  	})
   147  }
   148  
   149  // NeverEqualComparator returns -1 always
   150  func NeverEqualComparator() Comparator {
   151  	return ComparatorFunc(func(_, _ interface{}) int {
   152  		return -1
   153  	})
   154  }