source: josm/trunk/src/org/openstreetmap/josm/tools/AlphanumComparator.java@ 7253

Last change on this file since 7253 was 6985, checked in by Don-vip, 10 years ago

sonar - deprecated code

File size: 4.7 KB
Line 
1package org.openstreetmap.josm.tools;
2
3/*
4 * The Alphanum Algorithm is an improved sorting algorithm for strings
5 * containing numbers. Instead of sorting numbers in ASCII order like a standard
6 * sort, this algorithm sorts numbers in numeric order.
7 *
8 * The Alphanum Algorithm is discussed at http://www.DaveKoelle.com
9 *
10 *
11 * This library is free software; you can redistribute it and/or modify it under
12 * the terms of the GNU Lesser General Public License as published by the Free
13 * Software Foundation; either version 2.1 of the License, or any later version.
14 *
15 * This library is distributed in the hope that it will be useful, but WITHOUT
16 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
17 * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
18 * details.
19 *
20 * You should have received a copy of the GNU Lesser General Public License
21 * along with this library; if not, write to the Free Software Foundation, Inc.,
22 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
23 *
24 */
25import java.text.Collator;
26import java.util.Comparator;
27import java.util.Locale;
28
29/**
30 * The Alphanum Algorithm is an improved sorting algorithm for strings
31 * containing numbers: Instead of sorting numbers in ASCII order like a standard
32 * sort, this algorithm sorts numbers in numeric order.
33 *
34 * The Alphanum Algorithm is discussed at http://www.DaveKoelle.com
35 *
36 * This is an updated version with enhancements made by Daniel Migowski, Andre
37 * Bogus, and David Koelle and others.
38 *
39 */
40public class AlphanumComparator implements Comparator<String> {
41
42 private static final AlphanumComparator INSTANCE = new AlphanumComparator();
43
44 /**
45 * Replies the unique instance.
46 * @return the unique instance
47 */
48 public static AlphanumComparator getInstance() {
49 return INSTANCE;
50 }
51
52 /**
53 * Constructs a new Alphanum Comparator.
54 */
55 private AlphanumComparator() {
56 }
57
58 /**
59 * Length of string is passed in for improved efficiency (only need to
60 * calculate it once) *
61 */
62 private String getChunk(String s, int slength, int marker) {
63 StringBuilder chunk = new StringBuilder();
64 char c = s.charAt(marker);
65 chunk.append(c);
66 marker++;
67 if (Character.isDigit(c)) {
68 while (marker < slength) {
69 c = s.charAt(marker);
70 if (!Character.isDigit(c)) {
71 break;
72 }
73 chunk.append(c);
74 marker++;
75 }
76 } else {
77 while (marker < slength) {
78 c = s.charAt(marker);
79 if (Character.isDigit(c)) {
80 break;
81 }
82 chunk.append(c);
83 marker++;
84 }
85 }
86 return chunk.toString();
87 }
88
89 @Override
90 public int compare(String s1, String s2) {
91 if (s1 == null && s2 == null) {
92 return 0;
93 } else if (s1 == null) {
94 return -1;
95 } else if (s2 == null) {
96 return 1;
97 }
98
99 int thisMarker = 0;
100 int thatMarker = 0;
101 int s1Length = s1.length();
102 int s2Length = s2.length();
103
104 while (thisMarker < s1Length && thatMarker < s2Length) {
105 String thisChunk = getChunk(s1, s1Length, thisMarker);
106 thisMarker += thisChunk.length();
107
108 String thatChunk = getChunk(s2, s2Length, thatMarker);
109 thatMarker += thatChunk.length();
110
111 // If both chunks contain numeric characters, sort them numerically
112 int result;
113 if (Character.isDigit(thisChunk.charAt(0)) && Character.isDigit(thatChunk.charAt(0))) {
114 // Simple chunk comparison by length.
115 int thisChunkLength = thisChunk.length();
116 result = thisChunkLength - thatChunk.length();
117 // If equal, the first different number counts
118 if (result == 0) {
119 for (int i = 0; i < thisChunkLength; i++) {
120 result = thisChunk.charAt(i) - thatChunk.charAt(i);
121 if (result != 0) {
122 return result;
123 }
124 }
125 }
126 } else {
127 // Instantiate the collator
128 Collator compareOperator = Collator.getInstance(Locale.getDefault());
129 // Compare regardless of accented letters
130 compareOperator.setStrength(Collator.SECONDARY);
131 result = compareOperator.compare(thisChunk, thatChunk);
132 }
133
134 if (result != 0) {
135 return result;
136 }
137 }
138
139 return s1Length - s2Length;
140 }
141}
Note: See TracBrowser for help on using the repository browser.