/* * @(#) GComparator.java - Class for 'greater-than' comparators. * (c) 2000 Ivan Maidanski http://ivmai.chat.ru * Freeware class library sources. All rights reserved. ** * Language: Java [pure] * Tested with: JDK v1.1.6 * Last modified: 2000-12-27 18:00:00 GMT+03:00 */ /* * This software is the proprietary information of the author. ** * Permission to use, copy, and distribute this software and its * documentation for non-commercial purposes and without fee is * hereby granted provided that this copyright notice appears in all * copies. ** * This software should not be modified in any way; any found bug * should be reported to the author. ** * The author disclaims all warranties with regard to this software, * including all implied warranties of merchantability and fitness. * In no event shall the author be liable for any special, indirect * or consequential damages or any damages whatsoever resulting from * loss of use, data or profits, whether in an action of contract, * negligence or other tortuous action, arising out of or in * connection with the use or performance of this software. */ package ivmai.util; import java.io.Serializable; /** * Class for 'greater-than' comparators. ** * A binary predicate, which tests whether the first its argument is * greater than the second one, should extend this adapter class and * override greater(Object, Object), implementing own * comparison rules. Immutable interface is implemented * to underline that such comparators must have constant internal * state. The comparators may be used in serializable data * structures since Serializable interface is * implemented. In addition, this class provides the default * comparator for objects of Sortable interface, and of * String class and of the standard wrappers for the * primitive types. ** * @see Sortable * @see StrComparator ** * @version 2.0 * @author Ivan Maidanski ** * @since 1.8 */ public class GComparator implements Immutable, Serializable { /** * The class version unique identifier for serialization * interoperability. ** * @since 1.8 */ private static final long serialVersionUID = 1310911848083016948L; /** * The standard comparator for objects. ** * This constant field is initialized with the instantiation of * exactly this comparator. The implemented standard comparator * correctly orders any two objects of the class which implements * Sortable interface, or both of String * class, or both of the same primary-type value wrapper. ** * @see #greater(java.lang.Object, java.lang.Object) */ public static final GComparator INSTANCE = new GComparator(); /** * Constructs a new comparator. ** * This constructor is made public to allow custom * dynamic instantiation of this class. ** * @see #INSTANCE */ public GComparator() {} /** * The body of 'Greater-Than' comparator. ** * Tests whether or not the first specified object is greater than * the second one (according to the semantics). This method should * be overridden in the adapter subclasses. If any argument is not * instance of the expected type then standard comparison should be * performed (which is implemented in this method of this class). * The standard comparison of two objects is as follows: if * objA == objB then false is returned * else if objA is instance of Sortable then * greaterThan(objB) for objA is returned * else if objB is instance of Sortable then * !greaterThan(objA) for objB is returned, * else if objA is null then * true is returned, else if objA and * objB are both of the same class (either * Boolean, Byte, Short, * Integer, Long, Float, * Double, Character or * String) and the first (primary) value is greater * than the second one then true else * false is returned. Important notes: * String objects are compared here in the * case-sensitive manner; Float and Double * objects are compared here handling their zero and * NaN values specially (0 is greater than * -0 and NaN is greater than * non-NaN). ** * @param objA * the first compared argument (may be null). * @param objB * the second compared argument (may be null). * @return * true if and only if objA is greater than * objB. ** * @see #INSTANCE */ public boolean greater(Object objA, Object objB) { if (objA != objB) { if (objA instanceof Sortable) return ((Sortable)objA).greaterThan(objB); if (objB instanceof Sortable) return !((Sortable)objB).greaterThan(objA); if (objA == null) return true; if (objB != null) { if (objA instanceof String) return objB instanceof String && ((String)objA).compareTo((String)objB) > 0; if (objA instanceof Integer) return objB instanceof Integer && ((Integer)objA).intValue() > ((Integer)objB).intValue(); if (objA instanceof Long) return objB instanceof Long && ((Long)objA).longValue() > ((Long)objB).longValue(); if (objA instanceof Character) return objB instanceof Character && ((Character)objA).charValue() > ((Character)objB).charValue(); if (objA instanceof Short) return objB instanceof Short && ((Short)objA).intValue() > ((Short)objB).intValue(); if (objA instanceof Byte) return objB instanceof Byte && ((Byte)objA).intValue() > ((Byte)objB).intValue(); if (objA instanceof Boolean) return objB instanceof Boolean && ((Boolean)objA).booleanValue() && !((Boolean)objB).booleanValue(); if (objA instanceof Float && objB instanceof Float) { float floatB = ((Float)objB).floatValue(), floatA; return (floatA = ((Float)objA).floatValue()) > floatB || !(floatA < floatB) && Float.floatToIntBits(floatA) > Float.floatToIntBits(floatB); } if (objA instanceof Double && objB instanceof Double) { double doubleB = ((Double)objB).doubleValue(), doubleA; return (doubleA = ((Double)objA).doubleValue()) > doubleB || !(doubleA < doubleB) && Double.doubleToLongBits(doubleA) > Double.doubleToLongBits(doubleB); } } } return false; } }