Legend:
- Unmodified
- Added
- Removed
-
trunk/src/org/openstreetmap/josm/tools/AlphanumComparator.java
r18973 r18977 33 33 import java.io.Serializable; 34 34 import java.text.Collator; 35 import java.util.Arrays; 35 36 import java.util.Comparator; 36 37 … … 39 40 * containing numbers: Instead of sorting numbers in ASCII order like a standard 40 41 * sort, this algorithm sorts numbers in numeric order. 41 * 42 * The Alphanum Algorithm is discussed at http://www.DaveKoelle.com 43 * 42 * <p> 43 * The Alphanum Algorithm is discussed at 44 * <a href="https://web.archive.org/web/20210602024123/http://www.davekoelle.com/alphanum.html">DaveKoelle.com</a> 45 * <p> 44 46 * This is an updated version with enhancements made by Daniel Migowski, Andre 45 47 * Bogus, David Koelle and others. … … 51 53 52 54 private static final AlphanumComparator INSTANCE = new AlphanumComparator(); 55 /** 56 * A mapping from ASCII characters to the default {@link Collator} order. 57 * At writing, the default rules can be found in {@link sun.util.locale.provider.CollationRules#DEFAULTRULES}. 58 */ 59 private static final byte[] ASCII_MAPPING = new byte[128]; 60 static { 61 for (int i = 0; i < ASCII_MAPPING.length; i++) { 62 ASCII_MAPPING[i] = (byte) i; // This is kind of pointless, but it is the default ASCII ordering. 63 } 64 // The control characters are "ignored" 65 Arrays.fill(ASCII_MAPPING, 0, 32, (byte) 0); 66 ASCII_MAPPING[127] = 0; // DEL is ignored. 67 // We have 37 order overrides for symbols; ASCII tables has control characters through 31. 32-47 are symbols. 68 // After the symbols, we have 0-9, and then aA-zZ. 69 // The character order 70 final String order = " \r\t\n\f\u000b_,;:!?/.`^~'\"()[]{}@$*\\&#%+<=>|0123456789aAbBcCdDeEfFgGhHiIjJkKlLmMnNoOpPqQrRsStTuUvVwWxXyYzZ"; 71 for (int i = 0; i < order.length(); i++) { 72 char c = order.charAt(i); 73 ASCII_MAPPING[c] = (byte) (i + 1); 74 } 75 } 53 76 54 77 /** … … 64 87 */ 65 88 private AlphanumComparator() { 89 } 90 91 /** 92 * Compare two ASCII strings in a manner compatible with the default {@link Collator} 93 * @param string1 The first string to compare 94 * @param len1 The length of the first string 95 * @param string2 The second string to compare 96 * @param len2 The length of the second string 97 * @return See {@link String#compareToIgnoreCase(String)} (e.g. {@code string1.compareToIgnoreCase(string2)}). 98 */ 99 private static int compareString(String string1, int len1, String string2, int len2) { 100 int lim = Math.min(len1, len2); 101 int k = 0; 102 while (k < lim) { 103 final int c1 = ASCII_MAPPING[string1.charAt(k)]; 104 final int c2 = ASCII_MAPPING[string2.charAt(k)]; 105 if (c1 != c2) { 106 return c1 - c2; 107 } 108 k++; 109 } 110 return len1 - len2; 66 111 } 67 112 … … 107 152 for (int i = 0; i < stringLength; i++) { 108 153 char c = string.charAt(i); 109 if (c > = 128) {154 if (c > ASCII_MAPPING.length) { 110 155 return false; 111 156 } … … 139 184 // Check if both chunks are ascii only 140 185 if (isAscii(thisChunk, thisChunkLength) && isAscii(thatChunk, thatChunkLength)) { 141 return thisChunk.compareTo(thatChunk);186 return Utils.clamp(compareString(thisChunk, thisChunkLength, thatChunk, thatChunkLength), -1, 1); 142 187 } 143 188 // Instantiate the collator -
trunk/test/unit/org/openstreetmap/josm/data/osm/DefaultNameFormatterTest.java
r18106 r18977 79 79 80 80 // CHECKSTYLE.OFF: SingleSpaceSeparator 81 assertEquals( comparator.compare(p1, p2), -1); // p1 < p282 assertEquals( comparator.compare(p2, p1), 1); // p2 > p181 assertEquals(-1, comparator.compare(p1, p2)); // p1 < p2 82 assertEquals(1, comparator.compare(p2, p1)); // p2 > p1 83 83 84 assertEquals( comparator.compare(p1, p3), -1); // p1 < p385 assertEquals( comparator.compare(p3, p1), 1); // p3 > p186 assertEquals( comparator.compare(p2, p3), 1); // p2 > p387 assertEquals( comparator.compare(p3, p2), -1); // p3 < p284 assertEquals(-1, comparator.compare(p1, p3)); // p1 < p3 85 assertEquals(1, comparator.compare(p3, p1)); // p3 > p1 86 assertEquals(1, comparator.compare(p2, p3)); // p2 > p3 87 assertEquals(-1, comparator.compare(p3, p2)); // p3 < p2 88 88 // CHECKSTYLE.ON: SingleSpaceSeparator 89 89
Note:
See TracChangeset
for help on using the changeset viewer.