113 | | int thisMarker = 0; |
114 | | int thatMarker = 0; |
115 | | int s1Length = s1.length(); |
116 | | int s2Length = s2.length(); |
117 | | |
118 | | while (thisMarker < s1Length && thatMarker < s2Length) { |
119 | | String thisChunk = getChunk(s1, s1Length, thisMarker); |
120 | | thisMarker += thisChunk.length(); |
121 | | |
122 | | String thatChunk = getChunk(s2, s2Length, thatMarker); |
123 | | thatMarker += thatChunk.length(); |
124 | | |
125 | | // If both chunks contain numeric characters, sort them numerically |
126 | | int result; |
127 | | if (Character.isDigit(thisChunk.charAt(0)) && Character.isDigit(thatChunk.charAt(0))) { |
128 | | // Simple chunk comparison by length. |
129 | | int thisChunkLength = thisChunk.length(); |
130 | | result = thisChunkLength - thatChunk.length(); |
131 | | // If equal, the first different number counts |
132 | | if (result == 0) { |
133 | | for (int i = 0; i < thisChunkLength; i++) { |
134 | | result = thisChunk.charAt(i) - thatChunk.charAt(i); |
135 | | if (result != 0) { |
136 | | return result; |
137 | | } |
138 | | } |
139 | | } |
140 | | } else { |
141 | | // Instantiate the collator |
142 | | Collator compareOperator = Collator.getInstance(); |
143 | | // Compare regardless of accented letters |
144 | | compareOperator.setStrength(Collator.SECONDARY); |
145 | | result = compareOperator.compare(thisChunk, thatChunk); |
146 | | } |
| 116 | /** |
| 117 | * Compare two string chunks |
| 118 | * @param thisChunk The first chunk to compare |
| 119 | * @param thisChunkLength The length of the first chunk (for performance reasons) |
| 120 | * @param thatChunk The second chunk to compare |
| 121 | * @param thatChunkLength The length of the second chunk (for performance reasons) |
| 122 | * @return The {@link Comparator} result |
| 123 | */ |
| 124 | private static int compareChunk(String thisChunk, int thisChunkLength, String thatChunk, int thatChunkLength) { |
| 125 | int result; |
| 126 | if (Character.isDigit(thisChunk.charAt(0)) && Character.isDigit(thatChunk.charAt(0))) { |
| 127 | // Simple chunk comparison by length. |
| 128 | result = thisChunkLength - thatChunk.length(); |
| 129 | // If equal, the first different number counts |
| 130 | if (result == 0) { |
| 131 | for (int i = 0; i < thisChunkLength; i++) { |
| 132 | result = thisChunk.charAt(i) - thatChunk.charAt(i); |
| 133 | if (result != 0) { |
| 134 | return result; |
| 135 | } |
| 136 | } |
| 137 | } |
| 138 | } else { |
| 139 | // Check if both chunks are ascii only |
| 140 | if (isAscii(thisChunk, thisChunkLength) && isAscii(thatChunk, thatChunkLength)) { |
| 141 | return thisChunk.compareTo(thatChunk); |
| 142 | } |
| 143 | // Instantiate the collator |
| 144 | Collator compareOperator = Collator.getInstance(); |
| 145 | // Compare regardless of accented letters |
| 146 | compareOperator.setStrength(Collator.SECONDARY); |
| 147 | result = compareOperator.compare(thisChunk, thatChunk); |
| 148 | } |
| 149 | return result; |
| 150 | } |
| 151 | |
| 152 | @Override |
| 153 | public int compare(String s1, String s2) { |
| 154 | if (s1 == null && s2 == null) { |
| 155 | return 0; |
| 156 | } else if (s1 == null) { |
| 157 | return -1; |
| 158 | } else if (s2 == null) { |
| 159 | return 1; |
| 160 | } |
| 161 | |
| 162 | int thisMarker = 0; |
| 163 | int thatMarker = 0; |
| 164 | int s1Length = s1.length(); |
| 165 | int s2Length = s2.length(); |
| 166 | |
| 167 | while (thisMarker < s1Length && thatMarker < s2Length) { |
| 168 | final String thisChunk = getChunk(s1, s1Length, thisMarker); |
| 169 | final int thisChunkLength = thisChunk.length(); |
| 170 | thisMarker += thisChunkLength; |
| 171 | |
| 172 | String thatChunk = getChunk(s2, s2Length, thatMarker); |
| 173 | final int thatChunkLength = thatChunk.length(); |
| 174 | thatMarker += thatChunkLength; |
| 175 | |
| 176 | // If both chunks contain numeric characters, sort them numerically |
| 177 | int result = compareChunk(thisChunk, thisChunkLength, thatChunk, thatChunkLength); |