From 07daed5ffa27faee1770fd0fe292d3725b521a18 Mon Sep 17 00:00:00 2001 From: hneemann Date: Mon, 15 May 2017 20:32:32 +0200 Subject: [PATCH] refactoring of new string comparison --- .../digital/draw/library/ElementLibrary.java | 28 +----- .../draw/library/NumStringComparator.java | 85 +++++++++++++++++++ .../draw/library/NumStringComparatorTest.java | 27 ++++++ 3 files changed, 113 insertions(+), 27 deletions(-) create mode 100644 src/main/java/de/neemann/digital/draw/library/NumStringComparator.java create mode 100644 src/test/java/de/neemann/digital/draw/library/NumStringComparatorTest.java diff --git a/src/main/java/de/neemann/digital/draw/library/ElementLibrary.java b/src/main/java/de/neemann/digital/draw/library/ElementLibrary.java index 8d91b2c92..81fd4448d 100644 --- a/src/main/java/de/neemann/digital/draw/library/ElementLibrary.java +++ b/src/main/java/de/neemann/digital/draw/library/ElementLibrary.java @@ -31,8 +31,6 @@ import java.io.File; import java.io.IOException; import java.util.*; -import static java.lang.Character.isDigit; - /** * The ElementLibrary is responsible for storing all the components which can be used in a circuit. * Also the import of nested circuits is handled in this class. @@ -311,7 +309,7 @@ public class ElementLibrary implements Iterable File[] list = path.listFiles(); if (list != null) { ArrayList orderedList = new ArrayList<>(Arrays.asList(list)); - orderedList.sort((f1, f2) -> compareFilenames(f1.getName(), f2.getName())); + orderedList.sort((f1, f2) -> NumStringComparator.compareStr(f1.getName(), f2.getName())); for (File f : orderedList) { if (f.isDirectory()) { LibraryNode n = new LibraryNode(f.getName()); @@ -328,30 +326,6 @@ public class ElementLibrary implements Iterable } } - private int compareFilenames(String a, String b) { - int an = getNumber(a); - int bn = getNumber(b); - if (an > 0 && bn > 0) - return an - bn; - else - return a.compareToIgnoreCase(b); - } - - private int getNumber(String a) { - if (a.length() == 0) - return -1; - if (!isDigit(a.charAt(0))) - return -1; - - int n = 0; - int i = 0; - while (i < a.length() && isDigit(a.charAt(i))) { - n = n * 10 + (a.charAt(i) - '0'); - i++; - } - return n; - } - /** * Adds a listener to this library * diff --git a/src/main/java/de/neemann/digital/draw/library/NumStringComparator.java b/src/main/java/de/neemann/digital/draw/library/NumStringComparator.java new file mode 100644 index 000000000..4b4eca667 --- /dev/null +++ b/src/main/java/de/neemann/digital/draw/library/NumStringComparator.java @@ -0,0 +1,85 @@ +package de.neemann.digital.draw.library; + +import java.util.Comparator; + +import static java.lang.Character.isDigit; + +/** + * String comparator. + * If the string begins with a digit, the numbers are taken to compare the two strings. + * Used to ensure the 74xx components appear in the correct order instead of lexical order. + * Created by hneemann on 15.05.17. + */ +public final class NumStringComparator implements Comparator { + + private static final class InstanceHolder { + private static final NumStringComparator INSTANCE = new NumStringComparator(); + } + + /** + * Returns a comparator instance + * + * @return the singleton instance + */ + public NumStringComparator getInstance() { + return InstanceHolder.INSTANCE; + } + + private NumStringComparator() { + } + + @Override + public int compare(String a, String b) { + return compareStr(a, b); + } + + /** + * Compare two strings + * + * @param a a string + * @param b a string + * @return the comparison result + */ + public static int compareStr(String a, String b) { + NumString na = new NumString(a); + NumString nb = new NumString(b); + return na.compareTo(nb); + } + + private static final class NumString implements Comparable { + private final int num; + private final String str; + private final boolean isNum; + + private NumString(String str) { + str = str.trim(); + if (str.length() > 0 && isDigit(str.charAt(0))) { + isNum = true; + int n = 0; + int i = 0; + while (i < str.length() && isDigit(str.charAt(i))) { + n = n * 10 + (str.charAt(i) - '0'); + i++; + } + this.str = str.substring(i); + this.num = n; + } else { + this.str = str; + num = 0; + isNum = false; + } + } + + @Override + public int compareTo(NumString other) { + if (isNum && other.isNum) { + if (num != other.num) + return num - other.num; + else + return str.compareToIgnoreCase(other.str); + } else + return str.compareToIgnoreCase(other.str); + } + } + +} diff --git a/src/test/java/de/neemann/digital/draw/library/NumStringComparatorTest.java b/src/test/java/de/neemann/digital/draw/library/NumStringComparatorTest.java new file mode 100644 index 000000000..4df170e9d --- /dev/null +++ b/src/test/java/de/neemann/digital/draw/library/NumStringComparatorTest.java @@ -0,0 +1,27 @@ +package de.neemann.digital.draw.library; + +import junit.framework.TestCase; + +/** + * Created by hneemann on 15.05.17. + */ +public class NumStringComparatorTest extends TestCase { + + public void testSimple() { + checkLess("a", "b"); + checkLess("12a", "b"); + checkLess("2a", "12b"); + checkLess("2a", "2b"); + checkLess("2a", "02b"); + checkLess(" 2a", "02b"); + checkLess("2a", "2B"); + } + + private void checkLess(String a, String b) { + assertTrue(NumStringComparator.compareStr(a, b) < 0); + assertTrue(NumStringComparator.compareStr(b, a) > 0); + assertTrue(NumStringComparator.compareStr(a, a) == 0); + assertTrue(NumStringComparator.compareStr(b, b) == 0); + } + +} \ No newline at end of file