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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 2531 - (hide annotations) (download)
Fri May 8 20:25:12 2015 UTC (9 years, 1 month ago) by torben
File size: 5436 byte(s)
findbugs
1 torben 2495 package dk.daoas.daoadresseservice.util;
2    
3 torben 2531 import java.io.Serializable;
4    
5 torben 2495 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 torben 2531 public class NaturalOrderComparator<T> implements Comparator<T>, Serializable
37 torben 2495 {
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 torben 2531 }

  ViewVC Help
Powered by ViewVC 1.1.20