View Javadoc
1   package com.gisgraphy.street;
2   
3   import java.util.Comparator;
4   
5   import com.gisgraphy.domain.geoloc.entity.HouseNumber;
6   
7   /**
8    * implement a house number comparator based on the house number base on alphanumcomparator
9    * @author <a href="mailto:david.masclet@gisgraphy.com">David Masclet</a>
10   *
11   */
12  public class HouseNumberComparator implements Comparator<HouseNumber>{
13  
14  
15  	  private final boolean isDigit(char ch)
16  	    {
17  	        return ch >= 48 && ch <= 57;
18  	    }
19  
20  	    /** Length of string is passed in for improved efficiency (only need to calculate it once) **/
21  	    private final String getChunk(String s, int slength, int marker)
22  	    {
23  	        StringBuilder chunk = new StringBuilder();
24  	        char c = s.charAt(marker);
25  	        chunk.append(c);
26  	        marker++;
27  	        if (isDigit(c))
28  	        {
29  	            while (marker < slength)
30  	            {
31  	                c = s.charAt(marker);
32  	                if (!isDigit(c))
33  	                    break;
34  	                chunk.append(c);
35  	                marker++;
36  	            }
37  	        } else
38  	        {
39  	            while (marker < slength)
40  	            {
41  	                c = s.charAt(marker);
42  	                if (isDigit(c))
43  	                    break;
44  	                chunk.append(c);
45  	                marker++;
46  	            }
47  	        }
48  	        return chunk.toString();
49  	    }
50  
51  		public int compare(HouseNumber h1, HouseNumber h2) {
52  	    {
53  	    	if (h1==null){
54  	    		return 1;
55  	    	}
56  	    	if (h2==null){
57  	    		return -1;
58  	    	}
59  	       
60  	        String s1 = h1.getNumber();
61  	        String s2 = h2.getNumber();
62  	        if (s1==null){
63  	        	return 1;
64  	        }
65  	        if (s2==null){
66  	        	return -1;
67  	        }
68  
69  	        int thisMarker = 0;
70  	        int thatMarker = 0;
71  	        int s1Length = s1.length();
72  	        int s2Length = s2.length();
73  
74  	        while (thisMarker < s1Length && thatMarker < s2Length)
75  	        {
76  	            String thisChunk = getChunk(s1, s1Length, thisMarker);
77  	            thisMarker += thisChunk.length();
78  
79  	            String thatChunk = getChunk(s2, s2Length, thatMarker);
80  	            thatMarker += thatChunk.length();
81  
82  	            // If both chunks contain numeric characters, sort them numerically
83  	            int result = 0;
84  	            if (isDigit(thisChunk.charAt(0)) && isDigit(thatChunk.charAt(0)))
85  	            {
86  	                // Simple chunk comparison by length.
87  	                int thisChunkLength = thisChunk.length();
88  	                result = thisChunkLength - thatChunk.length();
89  	                // If equal, the first different number counts
90  	                if (result == 0)
91  	                {
92  	                    for (int i = 0; i < thisChunkLength; i++)
93  	                    {
94  	                        result = thisChunk.charAt(i) - thatChunk.charAt(i);
95  	                        if (result != 0)
96  	                        {
97  	                            return result;
98  	                        }
99  	                    }
100 	                }
101 	            } else
102 	            {
103 	                result = thisChunk.compareTo(thatChunk);
104 	            }
105 
106 	            if (result != 0)
107 	                return result;
108 	        }
109 
110 	        return s1Length - s2Length;
111 	    }
112 		}
113 
114 }