/[projects]/dao/DaoAdresseService/src/main/java/dk/daoas/daoadresseservice/util/NaturalOrderComparator.java
ViewVC logotype

Contents of /dao/DaoAdresseService/src/main/java/dk/daoas/daoadresseservice/util/NaturalOrderComparator.java

Parent Directory Parent Directory | Revision Log Revision Log


Revision 2531 - (show annotations) (download)
Fri May 8 20:25:12 2015 UTC (9 years ago) by torben
File size: 5436 byte(s)
findbugs
1 package dk.daoas.daoadresseservice.util;
2
3 import java.io.Serializable;
4
5 import java.util.Arrays;
6 import java.util.Collections;
7 import java.util.Comparator;
8 import java.util.List;
9
10 /*
11 NaturalOrderComparator.java -- Perform 'natural order' comparisons of strings in Java.
12 Copyright (C) 2003 by Pierre-Luc Paour <natorder@paour.com>
13
14 Based on the C version by Martin Pool, of which this is more or less a straight conversion.
15 Copyright (C) 2000 by Martin Pool <mbp@humbug.org.au>
16
17 This software is provided 'as-is', without any express or implied
18 warranty. In no event will the authors be held liable for any damages
19 arising from the use of this software.
20
21 Permission is granted to anyone to use this software for any purpose,
22 including commercial applications, and to alter it and redistribute it
23 freely, subject to the following restrictions:
24
25 1. The origin of this software must not be misrepresented; you must not
26 claim that you wrote the original software. If you use this software
27 in a product, an acknowledgment in the product documentation would be
28 appreciated but is not required.
29 2. Altered source versions must be plainly marked as such, and must not be
30 misrepresented as being the original software.
31 3. This notice may not be removed or altered from any source distribution.
32 */
33
34
35
36 public class NaturalOrderComparator<T> implements Comparator<T>, Serializable
37 {
38 int compareRight(String a, String b)
39 {
40 int bias = 0;
41 int ia = 0;
42 int ib = 0;
43
44 // The longest run of digits wins. That aside, the greatest
45 // value wins, but we can't know that it will until we've scanned
46 // both numbers to know that they have the same magnitude, so we
47 // remember it in BIAS.
48 for (;; ia++, ib++)
49 {
50 char ca = charAt(a, ia);
51 char cb = charAt(b, ib);
52
53 if (!Character.isDigit(ca) && !Character.isDigit(cb))
54 {
55 return bias;
56 }
57 else if (!Character.isDigit(ca))
58 {
59 return -1;
60 }
61 else if (!Character.isDigit(cb))
62 {
63 return +1;
64 }
65 else if (ca < cb)
66 {
67 if (bias == 0)
68 {
69 bias = -1;
70 }
71 }
72 else if (ca > cb)
73 {
74 if (bias == 0)
75 bias = +1;
76 }
77 else if (ca == 0 && cb == 0)
78 {
79 return bias;
80 }
81 }
82 }
83
84 public int compare(T o1, T o2)
85 {
86 String a = o1.toString();
87 String b = o2.toString();
88
89 int ia = 0, ib = 0;
90 int nza = 0, nzb = 0;
91 char ca, cb;
92 int result;
93
94 while (true)
95 {
96 // only count the number of zeroes leading the last number compared
97 nza = nzb = 0;
98
99 ca = charAt(a, ia);
100 cb = charAt(b, ib);
101
102 // skip over leading spaces or zeros
103 while (Character.isSpaceChar(ca) || ca == '0')
104 {
105 if (ca == '0')
106 {
107 nza++;
108 }
109 else
110 {
111 // only count consecutive zeroes
112 nza = 0;
113 }
114
115 ca = charAt(a, ++ia);
116 }
117
118 while (Character.isSpaceChar(cb) || cb == '0')
119 {
120 if (cb == '0')
121 {
122 nzb++;
123 }
124 else
125 {
126 // only count consecutive zeroes
127 nzb = 0;
128 }
129
130 cb = charAt(b, ++ib);
131 }
132
133 // process run of digits
134 if (Character.isDigit(ca) && Character.isDigit(cb))
135 {
136 if ((result = compareRight(a.substring(ia), b.substring(ib))) != 0)
137 {
138 return result;
139 }
140 }
141
142 if (ca == 0 && cb == 0)
143 {
144 // The strings compare the same. Perhaps the caller
145 // will want to call strcmp to break the tie.
146 return nza - nzb;
147 }
148
149 if (ca < cb)
150 {
151 return -1;
152 }
153 else if (ca > cb)
154 {
155 return +1;
156 }
157
158 ++ia;
159 ++ib;
160 }
161 }
162
163 static char charAt(String s, int i)
164 {
165 if (i >= s.length())
166 {
167 return 0;
168 }
169 else
170 {
171 return s.charAt(i);
172 }
173 }
174
175 public static void main(String[] args)
176 {
177 String[] strings = new String[] { "1-2", "1-02", "1-20", "10-20", "fred", "jane", "pic01",
178 "pic2", "pic02", "pic02a", "pic3", "pic4", "pic 4 else", "pic 5", "pic05", "pic 5",
179 "pic 5 something", "pic 6", "pic 7", "pic100", "pic100a", "pic120", "pic121",
180 "pic02000", "tom", "x2-g8", "x2-y7", "x2-y08", "x8-y8" };
181
182 List orig = Arrays.asList(strings);
183
184 System.out.println("Original: " + orig);
185
186 List scrambled = Arrays.asList(strings);
187 Collections.shuffle(scrambled);
188
189 System.out.println("Scrambled: " + scrambled);
190
191 Collections.sort(scrambled, new NaturalOrderComparator());
192
193 System.out.println("Sorted: " + scrambled);
194 }
195 }

  ViewVC Help
Powered by ViewVC 1.1.20