1 package org.simantics.document.server.client;
3 import java.util.Comparator;
6 * This is an updated version with enhancements made by Daniel Migowski,
7 * Andre Bogus, and David Koelle
9 * To convert to use Templates (Java 1.5+):
10 * - Change "implements Comparator" to "implements Comparator<String>"
11 * - Change "compare(Object o1, Object o2)" to "compare(String s1, String s2)"
12 * - Remove the type checking and casting in compare().
15 * Use the static "sort" method from the java.util.Collections class:
16 * Collections.sort(your list, new AlphanumComparator());
18 public class AlphanumericComparator implements Comparator<String>
20 private final boolean isDigit(char ch)
22 return ch >= 48 && ch <= 57;
25 /** Length of string is passed in for improved efficiency (only need to calculate it once) **/
26 private final String getChunk(String s, int slength, int marker)
28 StringBuilder chunk = new StringBuilder();
29 char c = s.charAt(marker);
34 while (marker < slength)
44 while (marker < slength)
53 return chunk.toString();
56 public int compare(String o1, String o2)
58 if (!(o1 instanceof String) || !(o2 instanceof String))
62 String s1 = (String)o1;
63 String s2 = (String)o2;
67 int s1Length = s1.length();
68 int s2Length = s2.length();
70 while (thisMarker < s1Length && thatMarker < s2Length)
72 String thisChunk = getChunk(s1, s1Length, thisMarker);
73 thisMarker += thisChunk.length();
75 String thatChunk = getChunk(s2, s2Length, thatMarker);
76 thatMarker += thatChunk.length();
78 // If both chunks contain numeric characters, sort them numerically
80 if (isDigit(thisChunk.charAt(0)) && isDigit(thatChunk.charAt(0)))
82 // Simple chunk comparison by length.
83 int thisChunkLength = thisChunk.length();
84 result = thisChunkLength - thatChunk.length();
85 // If equal, the first different number counts
88 for (int i = 0; i < thisChunkLength; i++)
90 result = thisChunk.charAt(i) - thatChunk.charAt(i);
99 result = thisChunk.compareTo(thatChunk);
106 return s1Length - s2Length;