Home | History | Annotate | Download | only in text
      1 //  2016 and later: Unicode, Inc. and others.
      2 // License & terms of use: http://www.unicode.org/copyright.html#License
      3 /**
      4 *******************************************************************************
      5 * Copyright (C) 1996-2012, International Business Machines Corporation and    *
      6 * others. All Rights Reserved.                                                *
      7 *******************************************************************************
      8 */
      9 package com.ibm.icu.text;
     10 
     11 /**
     12  * <p>A <code>CollationKey</code> represents a <code>String</code>
     13  * under the rules of a specific <code>Collator</code>
     14  * object. Comparing two <code>CollationKey</code>s returns the
     15  * relative order of the <code>String</code>s they represent.</p>
     16  *
     17  * <p>Since the rule set of <code>Collator</code>s can differ, the
     18  * sort orders of the same string under two different
     19  * <code>Collator</code>s might differ.  Hence comparing
     20  * <code>CollationKey</code>s generated from different
     21  * <code>Collator</code>s can give incorrect results.</p>
     22 
     23  * <p>Both the method
     24  * <code>CollationKey.compareTo(CollationKey)</code> and the method
     25  * <code>Collator.compare(String, String)</code> compare two strings
     26  * and returns their relative order.  The performance characterictics
     27  * of these two approaches can differ.</p>
     28  *
     29  * <p>During the construction of a <code>CollationKey</code>, the
     30  * entire source string is examined and processed into a series of
     31  * bits terminated by a null, that are stored in the <code>CollationKey</code>.
     32  * When <code>CollationKey.compareTo(CollationKey)</code> executes, it
     33  * performs bitwise comparison on the bit sequences.  This can incurs
     34  * startup cost when creating the <code>CollationKey</code>, but once
     35  * the key is created, binary comparisons are fast.  This approach is
     36  * recommended when the same strings are to be compared over and over
     37  * again.</p>
     38  *
     39  * <p>On the other hand, implementations of
     40  * <code>Collator.compare(String, String)</code> can examine and
     41  * process the strings only until the first characters differing in
     42  * order.  This approach is recommended if the strings are to be
     43  * compared only once.</p>
     44  *
     45  * <p>More information about the composition of the bit sequence can
     46  * be found in the
     47  * <a href="http://www.icu-project.org/userguide/Collate_ServiceArchitecture.html">
     48  * user guide</a>.</p>
     49  *
     50  * <p>The following example shows how <code>CollationKey</code>s can be used
     51  * to sort a list of <code>String</code>s.</p>
     52  * <blockquote>
     53  * <pre>
     54  * // Create an array of CollationKeys for the Strings to be sorted.
     55  * Collator myCollator = Collator.getInstance();
     56  * CollationKey[] keys = new CollationKey[3];
     57  * keys[0] = myCollator.getCollationKey("Tom");
     58  * keys[1] = myCollator.getCollationKey("Dick");
     59  * keys[2] = myCollator.getCollationKey("Harry");
     60  * sort( keys );
     61  * <br>
     62  * //...
     63  * <br>
     64  * // Inside body of sort routine, compare keys this way
     65  * if( keys[i].compareTo( keys[j] ) > 0 )
     66  *    // swap keys[i] and keys[j]
     67  * <br>
     68  * //...
     69  * <br>
     70  * // Finally, when we've returned from sort.
     71  * System.out.println( keys[0].getSourceString() );
     72  * System.out.println( keys[1].getSourceString() );
     73  * System.out.println( keys[2].getSourceString() );
     74  * </pre>
     75  * </blockquote>
     76  * </p>
     77  * <p>
     78  * This class is not subclassable
     79  * </p>
     80  * @see Collator
     81  * @see RuleBasedCollator
     82  * @author Syn Wee Quek
     83  * @stable ICU 2.8
     84  */
     85 public final class CollationKey implements Comparable<CollationKey>
     86 {
     87     /**
     88      * @internal
     89      */
     90     final java.text.CollationKey key;
     91 
     92     /**
     93      * @internal
     94      */
     95     CollationKey(java.text.CollationKey delegate) {
     96         this.key = delegate;
     97     }
     98 
     99     // public inner classes -------------------------------------------------
    100 
    101 //    /**
    102 //     * Options that used in the API CollationKey.getBound() for getting a
    103 //     * CollationKey based on the bound mode requested.
    104 //     * @stable ICU 2.6
    105 //     */
    106 //    public static final class BoundMode
    107 //    {
    108 //        /*
    109 //         * do not change the values assigned to the members of this enum.
    110 //         * Underlying code depends on them having these numbers
    111 //         */
    112 //
    113 //        /**
    114 //         * Lower bound
    115 //         * @stable ICU 2.6
    116 //         */
    117 //        public static final int LOWER = 0;
    118 //
    119 //        /**
    120 //         * Upper bound that will match strings of exact size
    121 //         * @stable ICU 2.6
    122 //         */
    123 //        public static final int UPPER = 1;
    124 //
    125 //        /**
    126 //         * Upper bound that will match all the strings that have the same
    127 //         * initial substring as the given string
    128 //         * @stable ICU 2.6
    129 //         */
    130 //        public static final int UPPER_LONG = 2;
    131 //
    132 //        /**
    133 //         * Number of bound mode
    134 //         * @stable ICU 2.6
    135 //         */
    136 //        public static final int COUNT = 3;
    137 //
    138 //        /**
    139 //         * Private Constructor
    140 //         */
    141 //        ///CLOVER:OFF
    142 //        private BoundMode(){}
    143 //        ///CLOVER:ON
    144 //    }
    145 
    146     // public constructor ---------------------------------------------------
    147 
    148 //    /**
    149 //     * CollationKey constructor.
    150 //     * This constructor is given public access, unlike the JDK version, to
    151 //     * allow access to users extending the Collator class. See
    152 //     * {@link Collator#getCollationKey(String)}.
    153 //     * @param source string this CollationKey is to represent
    154 //     * @param key array of bytes that represent the collation order of argument
    155 //     *            source terminated by a null
    156 //     * @see Collator
    157 //     * @stable ICU 2.8
    158 //     */
    159 //    public CollationKey(String source, byte key[])
    160 //    {
    161 //        throw new UnsupportedOperationException("Constructor not supported by com.ibm.icu.base");
    162 //    }
    163 
    164 //    /**
    165 //     * CollationKey constructor that forces key to release its internal byte
    166 //     * array for adoption. key will have a null byte array after this
    167 //     * construction.
    168 //     * @param source string this CollationKey is to represent
    169 //     * @param key RawCollationKey object that represents the collation order of
    170 //     *            argument source.
    171 //     * @see Collator
    172 //     * @see RawCollationKey
    173 //     * @stable ICU 2.8
    174 //     */
    175 //    public CollationKey(String source, RawCollationKey key)
    176 //    {
    177 //        throw new UnsupportedOperationException("Constructor not supported by com.ibm.icu.base");
    178 //    }
    179 
    180     // public getters -------------------------------------------------------
    181 
    182     /**
    183      * Return the source string that this CollationKey represents.
    184      * @return source string that this CollationKey represents
    185      * @stable ICU 2.8
    186      */
    187     public String getSourceString()
    188     {
    189         return key.getSourceString();
    190     }
    191 
    192     /**
    193      * <p>Duplicates and returns the value of this CollationKey as a sequence
    194      * of big-endian bytes terminated by a null.</p>
    195      *
    196      * <p>If two CollationKeys can be legitimately compared, then one can
    197      * compare the byte arrays of each to obtain the same result, e.g.
    198      * <pre>
    199      * byte key1[] = collationkey1.toByteArray();
    200      * byte key2[] = collationkey2.toByteArray();
    201      * int key, targetkey;
    202      * int i = 0;
    203      * do {
    204      *       key = key1[i] & 0xFF;
    205      *     targetkey = key2[i] & 0xFF;
    206      *     if (key &lt; targetkey) {
    207      *         System.out.println("String 1 is less than string 2");
    208      *         return;
    209      *     }
    210      *     if (targetkey &lt; key) {
    211      *         System.out.println("String 1 is more than string 2");
    212      *     }
    213      *     i ++;
    214      * } while (key != 0 && targetKey != 0);
    215      *
    216      * System.out.println("Strings are equal.");
    217      * </pre>
    218      * </p>
    219      * @return CollationKey value in a sequence of big-endian byte bytes
    220      *         terminated by a null.
    221      * @stable ICU 2.8
    222      */
    223     public byte[] toByteArray()
    224     {
    225         return key.toByteArray();
    226     }
    227 
    228     // public other methods -------------------------------------------------
    229 
    230     /**
    231      * <p>Compare this CollationKey to another CollationKey.  The
    232      * collation rules of the Collator that created this key are
    233      * applied.</p>
    234      *
    235      * <p><strong>Note:</strong> Comparison between CollationKeys
    236      * created by different Collators might return incorrect
    237      * results.  See class documentation.</p>
    238      *
    239      * @param target target CollationKey
    240      * @return an integer value.  If the value is less than zero this CollationKey
    241      *         is less than than target, if the value is zero they are equal, and
    242      *         if the value is greater than zero this CollationKey is greater
    243      *         than target.
    244      * @exception NullPointerException is thrown if argument is null.
    245      * @see Collator#compare(String, String)
    246      * @stable ICU 2.8
    247      */
    248     public int compareTo(CollationKey target)
    249     {
    250     	return key.compareTo(target.key);
    251     }
    252 
    253     /**
    254      * <p>Compare this CollationKey and the specified Object for
    255      * equality.  The collation rules of the Collator that created
    256      * this key are applied.</p>
    257      *
    258      * <p>See note in compareTo(CollationKey) for warnings about
    259      * possible incorrect results.</p>
    260      *
    261      * @param target the object to compare to.
    262      * @return true if the two keys compare as equal, false otherwise.
    263      * @see #compareTo(CollationKey)
    264      * @exception ClassCastException is thrown when the argument is not
    265      *            a CollationKey.  NullPointerException is thrown when the argument
    266      *            is null.
    267      * @stable ICU 2.8
    268      */
    269     public boolean equals(Object target)
    270     {
    271         if (!(target instanceof CollationKey)) {
    272             return false;
    273         }
    274 
    275         return equals((CollationKey)target);
    276     }
    277 
    278     /**
    279      * <p>
    280      * Compare this CollationKey and the argument target CollationKey for
    281      * equality.
    282      * The collation
    283      * rules of the Collator object which created these objects are applied.
    284      * </p>
    285      * <p>
    286      * See note in compareTo(CollationKey) for warnings of incorrect results
    287      * </p>
    288      * @param target the CollationKey to compare to.
    289      * @return true if two objects are equal, false otherwise.
    290      * @exception NullPointerException is thrown when the argument is null.
    291      * @stable ICU 2.8
    292      */
    293     public boolean equals(CollationKey target)
    294     {
    295     	return key.equals(target.key);
    296     }
    297 
    298     /**
    299      * <p>Returns a hash code for this CollationKey. The hash value is calculated
    300      * on the key itself, not the String from which the key was created. Thus
    301      * if x and y are CollationKeys, then x.hashCode(x) == y.hashCode()
    302      * if x.equals(y) is true. This allows language-sensitive comparison in a
    303      * hash table.
    304      * </p>
    305      * @return the hash value.
    306      * @stable ICU 2.8
    307      */
    308     public int hashCode()
    309     {
    310     	return key.hashCode();
    311     }
    312 
    313 //    /**
    314 //     * <p>
    315 //     * Produce a bound for the sort order of a given collation key and a
    316 //     * strength level. This API does not attempt to find a bound for the
    317 //     * CollationKey String representation, hence null will be returned in its
    318 //     * place.
    319 //     * </p>
    320 //     * <p>
    321 //     * Resulting bounds can be used to produce a range of strings that are
    322 //     * between upper and lower bounds. For example, if bounds are produced
    323 //     * for a sortkey of string "smith", strings between upper and lower
    324 //     * bounds with primary strength would include "Smith", "SMITH", "sMiTh".
    325 //     * </p>
    326 //     * <p>
    327 //     * There are two upper bounds that can be produced. If BoundMode.UPPER
    328 //     * is produced, strings matched would be as above. However, if a bound
    329 //     * is produced using BoundMode.UPPER_LONG is used, the above example will
    330 //     * also match "Smithsonian" and similar.
    331 //     * </p>
    332 //     * <p>
    333 //     * For more on usage, see example in test procedure
    334 //     * <a href="http://source.icu-project.org/repos/icu/icu4j/trunk/src/com/ibm/icu/dev/test/collator/CollationAPITest.java">
    335 //     * src/com/ibm/icu/dev/test/collator/CollationAPITest/TestBounds.
    336 //     * </a>
    337 //     * </p>
    338 //     * <p>
    339 //     * Collation keys produced may be compared using the <TT>compare</TT> API.
    340 //     * </p>
    341 //     * @param boundType Mode of bound required. It can be BoundMode.LOWER, which
    342 //     *              produces a lower inclusive bound, BoundMode.UPPER, that
    343 //     *              produces upper bound that matches strings of the same
    344 //     *              length or BoundMode.UPPER_LONG that matches strings that
    345 //     *              have the same starting substring as the source string.
    346 //     * @param noOfLevels Strength levels required in the resulting bound
    347 //     *                 (for most uses, the recommended value is PRIMARY). This
    348 //     *                 strength should be less than the maximum strength of
    349 //     *                 this CollationKey.
    350 //     *                 See users guide for explanation on the strength levels a
    351 //     *                 collation key can have.
    352 //     * @return the result bounded CollationKey with a valid sort order but
    353 //     *         a null String representation.
    354 //     * @exception IllegalArgumentException thrown when the strength level
    355 //     *            requested is higher than or equal to the strength in this
    356 //     *            CollationKey.
    357 //     *            In the case of an Exception, information
    358 //     *            about the maximum strength to use will be returned in the
    359 //     *            Exception. The user can then call getBound() again with the
    360 //     *            appropriate strength.
    361 //     * @see CollationKey
    362 //     * @see CollationKey.BoundMode
    363 //     * @see Collator#PRIMARY
    364 //     * @see Collator#SECONDARY
    365 //     * @see Collator#TERTIARY
    366 //     * @see Collator#QUATERNARY
    367 //     * @see Collator#IDENTICAL
    368 //     * @stable ICU 2.6
    369 //     */
    370 //    public CollationKey getBound(int boundType, int noOfLevels)
    371 //    {
    372 //        throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base");
    373 //    }
    374 
    375     /**
    376      * <p>
    377      * Merges this CollationKey with another. Only the sorting order of the
    378      * CollationKeys will be merged. This API does not attempt to merge the
    379      * String representations of the CollationKeys, hence null will be returned
    380      * as the String representation.
    381      * </p>
    382      * <p>
    383      * The strength levels are merged with their corresponding counterparts
    384      * (PRIMARIES with PRIMARIES, SECONDARIES with SECONDARIES etc.).
    385      * </p>
    386      * <p>
    387      * The merged String representation of the result CollationKey will be a
    388      * concatenation of the String representations of the 2 source
    389      * CollationKeys.
    390      * </p>
    391      * <p>
    392      * Between the values from the same level a separator is inserted.
    393      * example (uncompressed):
    394      * <pre>
    395      * 191B1D 01 050505 01 910505 00 and 1F2123 01 050505 01 910505 00
    396      * will be merged as
    397      * 191B1D 02 1F212301 050505 02 050505 01 910505 02 910505 00
    398      * </pre>
    399      * </p>
    400      * <p>
    401      * This allows for concatenating of first and last names for sorting, among
    402      * other things.
    403      * </p>
    404      * </p>
    405      * @param source CollationKey to merge with
    406      * @return a CollationKey that contains the valid merged sorting order
    407      *         with a null String representation,
    408      *         i.e. <tt>new CollationKey(null, merge_sort_order)</tt>
    409      * @exception IllegalArgumentException thrown if source CollationKey
    410      *            argument is null or of 0 length.
    411      * @stable ICU 2.6
    412      */
    413     public CollationKey merge(CollationKey source)
    414     {
    415         throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base");
    416     }
    417 }
    418