Index: trunk/src/org/openstreetmap/josm/tools/AlphanumComparator.java
===================================================================
--- trunk/src/org/openstreetmap/josm/tools/AlphanumComparator.java	(revision 18976)
+++ trunk/src/org/openstreetmap/josm/tools/AlphanumComparator.java	(revision 18977)
@@ -33,4 +33,5 @@
 import java.io.Serializable;
 import java.text.Collator;
+import java.util.Arrays;
 import java.util.Comparator;
 
@@ -39,7 +40,8 @@
  * containing numbers: Instead of sorting numbers in ASCII order like a standard
  * sort, this algorithm sorts numbers in numeric order.
- *
- * The Alphanum Algorithm is discussed at http://www.DaveKoelle.com
- *
+ * <p>
+ * The Alphanum Algorithm is discussed at
+ * <a href="https://web.archive.org/web/20210602024123/http://www.davekoelle.com/alphanum.html">DaveKoelle.com</a>
+ * <p>
  * This is an updated version with enhancements made by Daniel Migowski, Andre
  * Bogus, David Koelle and others.
@@ -51,4 +53,25 @@
 
     private static final AlphanumComparator INSTANCE = new AlphanumComparator();
+    /**
+     * A mapping from ASCII characters to the default {@link Collator} order.
+     * At writing, the default rules can be found in {@link sun.util.locale.provider.CollationRules#DEFAULTRULES}.
+     */
+    private static final byte[] ASCII_MAPPING = new byte[128];
+    static {
+        for (int i = 0; i < ASCII_MAPPING.length; i++) {
+            ASCII_MAPPING[i] = (byte) i; // This is kind of pointless, but it is the default ASCII ordering.
+        }
+        // The control characters are "ignored"
+        Arrays.fill(ASCII_MAPPING, 0, 32, (byte) 0);
+        ASCII_MAPPING[127] = 0; // DEL is ignored.
+        // We have 37 order overrides for symbols; ASCII tables has control characters through 31. 32-47 are symbols.
+        // After the symbols, we have 0-9, and then aA-zZ.
+        // The character order
+        final String order = " \r\t\n\f\u000b_,;:!?/.`^~'\"()[]{}@$*\\&#%+<=>|0123456789aAbBcCdDeEfFgGhHiIjJkKlLmMnNoOpPqQrRsStTuUvVwWxXyYzZ";
+        for (int i = 0; i < order.length(); i++) {
+            char c = order.charAt(i);
+            ASCII_MAPPING[c] = (byte) (i + 1);
+        }
+    }
 
     /**
@@ -64,4 +87,26 @@
      */
     private AlphanumComparator() {
+    }
+
+    /**
+     * Compare two ASCII strings in a manner compatible with the default {@link Collator}
+     * @param string1 The first string to compare
+     * @param len1 The length of the first string
+     * @param string2 The second string to compare
+     * @param len2 The length of the second string
+     * @return See {@link String#compareToIgnoreCase(String)} (e.g. {@code string1.compareToIgnoreCase(string2)}).
+     */
+    private static int compareString(String string1, int len1, String string2, int len2) {
+        int lim = Math.min(len1, len2);
+        int k = 0;
+        while (k < lim) {
+            final int c1 = ASCII_MAPPING[string1.charAt(k)];
+            final int c2 = ASCII_MAPPING[string2.charAt(k)];
+            if (c1 != c2) {
+                return c1 - c2;
+            }
+            k++;
+        }
+        return len1 - len2;
     }
 
@@ -107,5 +152,5 @@
         for (int i = 0; i < stringLength; i++) {
             char c = string.charAt(i);
-            if (c >= 128) {
+            if (c > ASCII_MAPPING.length) {
                 return false;
             }
@@ -139,5 +184,5 @@
             // Check if both chunks are ascii only
             if (isAscii(thisChunk, thisChunkLength) && isAscii(thatChunk, thatChunkLength)) {
-                return thisChunk.compareTo(thatChunk);
+                return Utils.clamp(compareString(thisChunk, thisChunkLength, thatChunk, thatChunkLength), -1, 1);
             }
             // Instantiate the collator
Index: trunk/test/unit/org/openstreetmap/josm/data/osm/DefaultNameFormatterTest.java
===================================================================
--- trunk/test/unit/org/openstreetmap/josm/data/osm/DefaultNameFormatterTest.java	(revision 18976)
+++ trunk/test/unit/org/openstreetmap/josm/data/osm/DefaultNameFormatterTest.java	(revision 18977)
@@ -79,11 +79,11 @@
 
             // CHECKSTYLE.OFF: SingleSpaceSeparator
-            assertEquals(comparator.compare(p1, p2), -1); // p1 < p2
-            assertEquals(comparator.compare(p2, p1),  1); // p2 > p1
+            assertEquals(-1, comparator.compare(p1, p2)); // p1 < p2
+            assertEquals(1,  comparator.compare(p2, p1)); // p2 > p1
 
-            assertEquals(comparator.compare(p1, p3), -1); // p1 < p3
-            assertEquals(comparator.compare(p3, p1),  1); // p3 > p1
-            assertEquals(comparator.compare(p2, p3),  1); // p2 > p3
-            assertEquals(comparator.compare(p3, p2), -1); // p3 < p2
+            assertEquals(-1, comparator.compare(p1, p3)); // p1 < p3
+            assertEquals(1,  comparator.compare(p3, p1)); // p3 > p1
+            assertEquals(1,  comparator.compare(p2, p3)); // p2 > p3
+            assertEquals(-1, comparator.compare(p3, p2)); // p3 < p2
             // CHECKSTYLE.ON: SingleSpaceSeparator
 
