mirror of
https://github.com/eclipse-sailing-analytics/sailing-analytics.git
synced 2026-10-10 22:30:56 +00:00
extracted NaturalComparator into separate compilation unit
This commit is contained in:
1 parent
0d648230ea
commit
91f686cf4a
5 files changed
+83
-79
No files matched your search
Executable
+79
@@ -0,0 +1,79 @@
|
||||
package com.sap.sailing.domain.common.impl;
|
||||
|
||||
import java.util.Comparator;
|
||||
|
||||
/**
|
||||
* Natural Order String Comparison inspired by the idea of Martin Pool and Dave Koelle.
|
||||
* <p>
|
||||
*
|
||||
* Natural order compares mixed (alphanumeric) string in a more intuitive way: a < a0 < a1 < a1a < a1b <
|
||||
* a2 < a10 < a20
|
||||
*
|
||||
*/
|
||||
public class NaturalComparator implements Comparator<String> {
|
||||
|
||||
/**
|
||||
* Compare the passed strings in natural order.
|
||||
*/
|
||||
@Override
|
||||
public int compare(String a, String b) {
|
||||
int result = 0;
|
||||
int aIndex = 0;
|
||||
int bIndex = 0;
|
||||
int aLength = a.length();
|
||||
int bLength = b.length();
|
||||
|
||||
while (aIndex < aLength && bIndex < bLength) {
|
||||
// Get next block of all-char or all-digit substring
|
||||
String aBlock = getBlock(a, aIndex);
|
||||
aIndex += aBlock.length();
|
||||
String bBlock = getBlock(b, bIndex);
|
||||
bIndex += bBlock.length();
|
||||
|
||||
// Compare all-digit blocks as numbers - all-char blocks as strings
|
||||
if (Character.isDigit(aBlock.charAt(0)) && Character.isDigit(bBlock.charAt(0))) {
|
||||
result = Integer.valueOf(aBlock).compareTo(Integer.valueOf(bBlock));
|
||||
} else {
|
||||
result = aBlock.compareTo(bBlock);
|
||||
}
|
||||
|
||||
if (result != 0) {
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
// Strings may be of different size
|
||||
return aLength - bLength;
|
||||
}
|
||||
|
||||
private String getBlock(String value, int index) {
|
||||
int valueLength = value.length();
|
||||
StringBuilder blockBuilder = new StringBuilder();
|
||||
|
||||
char ch = value.charAt(index++);
|
||||
blockBuilder.append(ch);
|
||||
|
||||
if (Character.isDigit(ch)) {
|
||||
while (index < valueLength) {
|
||||
ch = value.charAt(index++);
|
||||
if (!Character.isDigit(ch)) {
|
||||
break;
|
||||
} else {
|
||||
blockBuilder.append(ch);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
while (index < valueLength) {
|
||||
ch = value.charAt(index++);
|
||||
if (Character.isDigit(ch)) {
|
||||
break;
|
||||
} else {
|
||||
blockBuilder.append(ch);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return blockBuilder.toString();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -2,7 +2,6 @@ package com.sap.sailing.domain.common.impl;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.Collection;
|
||||
import java.util.Comparator;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
|
||||
@@ -232,79 +231,5 @@ public class Util {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Natural Order String Comparison inspired by the idea of Martin Pool and Dave Koelle.
|
||||
*
|
||||
* Natural order compares mixed (alphanumeric) string in a more intuitive way:
|
||||
* a < a0 < a1 < a1a < a1b < a2 < a10 < a20
|
||||
*
|
||||
*/
|
||||
public static class NaturalComparator implements Comparator<String> {
|
||||
|
||||
/**
|
||||
* Compare the passed strings in natural order.
|
||||
*/
|
||||
@Override
|
||||
public int compare(String a, String b) {
|
||||
int result = 0;
|
||||
int aIndex = 0;
|
||||
int bIndex = 0;
|
||||
int aLength = a.length();
|
||||
int bLength = b.length();
|
||||
|
||||
while(aIndex < aLength && bIndex < bLength) {
|
||||
// Get next block of all-char or all-digit substring
|
||||
String aBlock = getBlock(a, aIndex);
|
||||
aIndex += aBlock.length();
|
||||
String bBlock = getBlock(b, bIndex);
|
||||
bIndex += bBlock.length();
|
||||
|
||||
// Compare all-digit blocks as numbers - all-char blocks as strings
|
||||
if (Character.isDigit(aBlock.charAt(0)) && Character.isDigit(bBlock.charAt(0))) {
|
||||
result = Integer.valueOf(aBlock).compareTo(Integer.valueOf(bBlock));
|
||||
} else {
|
||||
result = aBlock.compareTo(bBlock);
|
||||
}
|
||||
|
||||
if (result != 0) {
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
// Strings may be of different size
|
||||
return aLength - bLength;
|
||||
}
|
||||
|
||||
private String getBlock(String value, int index) {
|
||||
int valueLength = value.length();
|
||||
StringBuilder blockBuilder = new StringBuilder();
|
||||
|
||||
char ch = value.charAt(index++);
|
||||
blockBuilder.append(ch);
|
||||
|
||||
if (Character.isDigit(ch)) {
|
||||
while (index < valueLength) {
|
||||
ch = value.charAt(index++);
|
||||
if (!Character.isDigit(ch)) {
|
||||
break;
|
||||
} else {
|
||||
blockBuilder.append(ch);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
while (index < valueLength) {
|
||||
ch = value.charAt(index++);
|
||||
if (Character.isDigit(ch)) {
|
||||
break;
|
||||
} else {
|
||||
blockBuilder.append(ch);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return blockBuilder.toString();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
+1
-1
@@ -6,7 +6,7 @@ import static org.junit.Assert.assertTrue;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
||||
import com.sap.sailing.domain.common.impl.Util.NaturalComparator;
|
||||
import com.sap.sailing.domain.common.impl.NaturalComparator;
|
||||
|
||||
public class NaturalComparatorTest {
|
||||
|
||||
|
||||
+1
-1
@@ -2,7 +2,7 @@ package com.sap.sailing.gwt.ui.regattaoverview;
|
||||
|
||||
import java.util.Comparator;
|
||||
|
||||
import com.sap.sailing.domain.common.impl.Util.NaturalComparator;
|
||||
import com.sap.sailing.domain.common.impl.NaturalComparator;
|
||||
import com.sap.sailing.gwt.ui.shared.RegattaOverviewEntryDTO;
|
||||
|
||||
public class RegattaRaceStatesComparator implements Comparator<RegattaOverviewEntryDTO> {
|
||||
|
||||
Reference in new issue
Block a user