com.netradius.commons.lang.AlphanumComparator Maven / Gradle / Ivy
/**
* Copyright (c) 2010-2019, NetRadius, LLC
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of NetRadius, LLC nor the names of its
* contributors may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package com.netradius.commons.lang;
import java.util.Comparator;
/**
* Compares strings in a human expected way using a modified version of the Alphanum Algorithm
* as described on http://www.davekoelle.com/alphanum.html. This clean room implementation is
* faster and correctly lexicographically sorts all non-digit characters using Character.compareTo()
* to provide more accurate results.
*
* @author Erik R. Jensen
*/
public class AlphanumComparator implements Comparator {
private static final int ONE = 48;
private static final int NINE = 57;
private String digits(String s, int len, char c, int pos) {
StringBuilder sb = new StringBuilder().append(c);
pos++;
while (pos < len) {
c = s.charAt(pos);
if (c >= ONE && c <= NINE) {
sb.append(c);
pos++;
continue;
}
break;
}
return sb.toString();
}
@Override
public int compare(String s1, String s2) {
int s1len = s1.length();
int s1cnt = 0;
int s2len = s2.length();
int s2cnt = 0;
while (s1cnt < s1len && s2cnt < s2len) {
char c1 = s1.charAt(s1cnt);
char c2 = s2.charAt(s2cnt);
if (c1 >= ONE && c1 <= NINE && c2 >= ONE && c2 <= NINE) { // Both are digits
String d1 = digits(s1, s1len, c1, s1cnt);
String d2 = digits(s2, s2len, c2, s2cnt);
int i1 = Integer.valueOf(d1);
int i2 = Integer.valueOf(d2);
if (i1 == i2) {
s1cnt = s1cnt + d1.length();
s2cnt = s2cnt + d2.length();
continue;
}
return i1 - i2;
} else if (c1 == c2) {
s1cnt++;
s2cnt++;
continue;
}
return Character.valueOf(c1).compareTo(c2);
}
return s1len - s2len;
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy