2  * The Alphanum Algorithm is an improved sorting algorithm for strings 
   3  * containing numbers.  Instead of sorting numbers in ASCII order like 
   4  * a standard sort, this algorithm sorts numbers in numeric order. 
   6  * The Alphanum Algorithm is discussed at http://www.DaveKoelle.com 
   9  * This library is free software; you can redistribute it and/or 
  10  * modify it under the terms of the GNU Lesser General Public 
  11  * License as published by the Free Software Foundation; either 
  12  * version 2.1 of the License, or any later version. 
  14  * This library is distributed in the hope that it will be useful, 
  15  * but WITHOUT ANY WARRANTY; without even the implied warranty of 
  16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU 
  17  * Lesser General Public License for more details. 
  19  * You should have received a copy of the GNU Lesser General Public 
  20  * License along with this library; if not, write to the Free Software 
  21  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA 
  25 package third_parties
.daveKoeller
; 
  26 import java
.text
.Collator
; 
  28 import java
.util
.Comparator
; 
  30 import com
.owncloud
.android
.datamodel
.OCFile
; 
  33  * This is an updated version with enhancements made by Daniel Migowski, 
  34  * Andre Bogus, and David Koelle 
  36  * To convert to use Templates (Java 1.5+): 
  37  *   - Change "implements Comparator" to "implements Comparator<String>" 
  38  *   - Change "compare(Object o1, Object o2)" to "compare(String s1, String s2)" 
  39  *   - Remove the type checking and casting in compare(). 
  42  *   Use the static "sort" method from the java.util.Collections class: 
  43  *   Collections.sort(your list, new AlphanumComparator()); 
  45 public class AlphanumComparator 
implements Comparator
<OCFile
> 
  47     private final boolean isDigit(char ch
) 
  49         return ch 
>= 48 && ch 
<= 57; 
  52     /** Length of string is passed in for improved efficiency (only need to calculate it once) **/ 
  53     private final String 
getChunk(String s
, int slength
, int marker
){ 
  54         StringBuilder chunk 
= new StringBuilder(); 
  55         char c 
= s
.charAt(marker
); 
  59             while (marker 
< slength
) 
  68             while (marker 
< slength
) 
  77         return chunk
.toString(); 
  80     public int compare(OCFile o1
, OCFile o2
){ 
  81         String s1 
= o1
.getRemotePath().toLowerCase(); 
  82         String s2 
= o2
.getRemotePath().toLowerCase(); 
  84         return compare(s1
, s2
); 
  87     public int compare(File f1
, File f2
){ 
  88         String s1 
= f1
.getPath().toLowerCase(); 
  89         String s2 
= f2
.getPath().toLowerCase(); 
  91         return compare(s1
, s2
); 
  94     public int compare(String s1
, String s2
) { 
  97         int s1Length 
= s1
.length(); 
  98         int s2Length 
= s2
.length(); 
 100         while (thisMarker 
< s1Length 
&& thatMarker 
< s2Length
) { 
 101             String thisChunk 
= getChunk(s1
, s1Length
, thisMarker
); 
 102             thisMarker 
+= thisChunk
.length(); 
 104             String thatChunk 
= getChunk(s2
, s2Length
, thatMarker
); 
 105             thatMarker 
+= thatChunk
.length(); 
 107             // If both chunks contain numeric characters, sort them numerically 
 109             if (isDigit(thisChunk
.charAt(0)) && isDigit(thatChunk
.charAt(0))) { 
 110                 // Simple chunk comparison by length. 
 111                 int thisChunkLength 
= thisChunk
.length(); 
 112                 result 
= thisChunkLength 
- thatChunk
.length(); 
 113                 // If equal, the first different number counts 
 115                     for (int i 
= 0; i 
< thisChunkLength
; i
++) { 
 116                         result 
= thisChunk
.charAt(i
) - thatChunk
.charAt(i
); 
 123                 Collator collator 
= Collator
.getInstance(); 
 124                 collator
.setStrength(Collator
.PRIMARY
); 
 125                 result 
= collator
.compare(thisChunk
, thatChunk
); 
 132         return s1Length 
- s2Length
;