-
Notifications
You must be signed in to change notification settings - Fork 331
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
fix: Add numeric comparator that preserves leading zeros
- Loading branch information
Showing
6 changed files
with
181 additions
and
12 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
package jmri.util; | ||
|
||
import java.util.Comparator; | ||
|
||
import jmri.NamedBean; | ||
|
||
/** | ||
* Compare two NamedBeans using the {@link PreferNumericComparator} against | ||
* {@link NamedBean#getSystemName()} for each NamedBean. | ||
* <p> | ||
* If the requirement is that {@link Comparator#compare(Object, Object)} return | ||
* 0 for two numerically identical NamedBean System Names (i.e. | ||
* {@code IT42 == IT0042}), use {@link NamedBeanComparator}, but if the | ||
* requirement is that System Names should be numerically ordered, but that | ||
* non-identical representations of numbers should be different, (i.e. | ||
* {@code IT42 != IT0042}, but order should be | ||
* {@code IT3, IT4, IT5, IT42, IT0042, IT50}), use this Comparator. | ||
* | ||
* @author Randall Wood Copyright 2019 | ||
* @param <B> the type of NamedBean to compare | ||
*/ | ||
public class NamedBeanPreferNumericComparator<B extends NamedBean> extends NamedBeanComparator<B> { | ||
|
||
private final PreferNumericComparator comparator = new PreferNumericComparator(); | ||
|
||
@Override | ||
public int compare(B n1, B n2) { | ||
return comparator.compare(n1.getSystemName(), n2.getSystemName()); | ||
} | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,12 +1,30 @@ | ||
package jmri.util; | ||
|
||
import java.util.Comparator; | ||
|
||
/** | ||
* Originally, this attempted to compare as Integer, and then alphanumeric. | ||
* It's now deprecated in favor of the more general AlphanumComparator | ||
* @deprecated 4.11.1 use AlphanumComparator | ||
* | ||
* @author Bob Jacobsen Copyright (C) 2013, 2017 | ||
* Perform an comparison using {@link AlphanumComparator}, followed up with a | ||
* standard String comparison if | ||
* {@link AlphanumComparator#compare(String, String)} returns 0. | ||
* <p> | ||
* If the requirement is that {@link Comparator#compare(Object, Object)} return | ||
* 0 for two numerically identical Strings (i.e. {@code 42 == 0042}), use | ||
* {@link AlphanumComparator}, but if the requirement is that Strings should be | ||
* numerically ordered, but that non-identical representations should be | ||
* different, (i.e. {@code 42 != 0042}, but order should be | ||
* {@code 3, 4, 5, 42, 0042, 50}), use this Comparator, since the standard | ||
* String comparator will not order numbers correctly. | ||
* | ||
* @author Randall Wood Copyright 2019 | ||
*/ | ||
@Deprecated // in 4.11.1 use AlphanumComparator | ||
public class PreferNumericComparator extends AlphanumComparator { | ||
|
||
@Override | ||
public int compare(String s1, String s2) { | ||
int comparison = super.compare(s1, s2); | ||
if (comparison == 0) { | ||
return s1.compareTo(s2); | ||
} | ||
return comparison; | ||
} | ||
} |
119 changes: 119 additions & 0 deletions
119
java/test/jmri/util/NamedBeanPreferNumericComparatorTest.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,119 @@ | ||
package jmri.util; | ||
|
||
import org.junit.After; | ||
import org.junit.Assert; | ||
import org.junit.Before; | ||
import org.junit.Test; | ||
|
||
import jmri.*; | ||
|
||
/** | ||
* @author Paul Bender Copyright (C) 2017 | ||
*/ | ||
public class NamedBeanPreferNumericComparatorTest { | ||
|
||
@Test | ||
public void testOneLetterCases() { | ||
NamedBeanPreferNumericComparator<Turnout> t = new NamedBeanPreferNumericComparator<>(); | ||
|
||
Turnout it1 = InstanceManager.getDefault(TurnoutManager.class).provideTurnout("IT1"); | ||
Turnout it10 = InstanceManager.getDefault(TurnoutManager.class).provideTurnout("IT10"); | ||
Turnout it2 = InstanceManager.getDefault(TurnoutManager.class).provideTurnout("IT2"); | ||
Turnout it01 = InstanceManager.getDefault(TurnoutManager.class).provideTurnout("IT01"); | ||
|
||
Assert.assertEquals("IT1 == IT1", 0, t.compare(it1, it1)); | ||
|
||
Assert.assertEquals("IT1 < IT2", -1, t.compare(it1, it2)); | ||
Assert.assertEquals("IT2 > IT1", +1, t.compare(it2, it1)); | ||
|
||
Assert.assertEquals("IT10 > IT2", +1, t.compare(it10, it2)); | ||
Assert.assertEquals("IT2 < IT10", -1, t.compare(it2, it10)); | ||
|
||
Assert.assertNotEquals("IT1 != IT01", 0, t.compare(it1, it01)); | ||
Assert.assertEquals("IT01 < IT1", -1, t.compare(it01, it1)); | ||
Assert.assertEquals("IT1 > IT01", +1, t.compare(it1, it01)); | ||
} | ||
|
||
@Test | ||
public void testTwoLetterCases() { | ||
NamedBeanPreferNumericComparator<Turnout> t = new NamedBeanPreferNumericComparator<>(); | ||
|
||
Turnout i2t1 = InstanceManager.getDefault(TurnoutManager.class).provideTurnout("I2T1"); | ||
Turnout i2t10 = InstanceManager.getDefault(TurnoutManager.class).provideTurnout("I2T10"); | ||
Turnout i2t2 = InstanceManager.getDefault(TurnoutManager.class).provideTurnout("I2T2"); | ||
|
||
Assert.assertEquals("I2T1 == I2T1", 0, t.compare(i2t1, i2t1)); | ||
|
||
Assert.assertEquals("I2T1 < I2T2", -1, t.compare(i2t1, i2t2)); | ||
Assert.assertEquals("I2T2 > I2T1", +1, t.compare(i2t2, i2t1)); | ||
|
||
Assert.assertEquals("I2T10 > I2T2", +1, t.compare(i2t10, i2t2)); | ||
Assert.assertEquals("I2T2 < I2T10", -1, t.compare(i2t2, i2t10)); | ||
} | ||
|
||
@Test | ||
public void testThreeLetterCases() { | ||
NamedBeanPreferNumericComparator<Turnout> t = new NamedBeanPreferNumericComparator<>(); | ||
|
||
Turnout i23t1 = InstanceManager.getDefault(TurnoutManager.class).provideTurnout("I23T1"); | ||
Turnout i23t10 = InstanceManager.getDefault(TurnoutManager.class).provideTurnout("I23T10"); | ||
Turnout i23t2 = InstanceManager.getDefault(TurnoutManager.class).provideTurnout("I23T2"); | ||
|
||
Assert.assertEquals("I23T1 == I23T1", 0, t.compare(i23t1, i23t1)); | ||
|
||
Assert.assertEquals("I23T1 < I23T2", -1, t.compare(i23t1, i23t2)); | ||
Assert.assertEquals("I23T2 > I23T1", +1, t.compare(i23t2, i23t1)); | ||
|
||
Assert.assertEquals("I23T10 > I23T2", +1, t.compare(i23t10, i23t2)); | ||
Assert.assertEquals("I23T2 < I23T10", -1, t.compare(i23t2, i23t10)); | ||
} | ||
|
||
boolean hit = false; | ||
|
||
@Test | ||
public void testSystemSpecificCase() { | ||
NamedBeanComparator<Turnout> t = new NamedBeanComparator<>(); | ||
|
||
// this just checks that the local sort is called | ||
Turnout it1 = InstanceManager.getDefault(TurnoutManager.class).provideTurnout("IT1"); | ||
Turnout it2 = new jmri.implementation.AbstractTurnout("IT2") { | ||
|
||
@Override | ||
protected void forwardCommandChangeToLayout(int s) { | ||
} | ||
|
||
@Override | ||
protected void turnoutPushbuttonLockout(boolean b) { | ||
} | ||
|
||
@Override | ||
public int compareSystemNameSuffix(String suffix1, String suffix2, jmri.NamedBean n) { | ||
hit = true; | ||
return super.compareSystemNameSuffix(suffix1, suffix2, n); | ||
} | ||
}; | ||
|
||
hit = false; | ||
Assert.assertEquals("IT1 < IT2", -1, t.compare(it1, it2)); | ||
Assert.assertFalse(hit); | ||
|
||
hit = false; | ||
Assert.assertEquals("IT2 < IT1", +1, t.compare(it2, it1)); | ||
Assert.assertTrue(hit); | ||
} | ||
|
||
// The minimal setup for log4J | ||
@Before | ||
public void setUp() { | ||
JUnitUtil.setUp(); | ||
} | ||
|
||
@After | ||
public void tearDown() { | ||
JUnitUtil.tearDown(); | ||
} | ||
|
||
// private final static Logger log = | ||
// LoggerFactory.getLogger(NamedBeanComparatorTest.class); | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters