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 < targetkey) { 207 * System.out.println("String 1 is less than string 2"); 208 * return; 209 * } 210 * if (targetkey < 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