You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@commons.apache.org by ba...@apache.org on 2007/11/13 04:18:37 UTC
svn commit: r594409 - in /commons/proper/lang/trunk/src:
java/org/apache/commons/lang/StringUtils.java
test/org/apache/commons/lang/StringUtilsTest.java
Author: bayard
Date: Mon Nov 12 19:18:36 2007
New Revision: 594409
URL: http://svn.apache.org/viewvc?rev=594409&view=rev
Log:
Applying Scott Johnson's great work in LANG-269
Modified:
commons/proper/lang/trunk/src/java/org/apache/commons/lang/StringUtils.java
commons/proper/lang/trunk/src/test/org/apache/commons/lang/StringUtilsTest.java
Modified: commons/proper/lang/trunk/src/java/org/apache/commons/lang/StringUtils.java
URL: http://svn.apache.org/viewvc/commons/proper/lang/trunk/src/java/org/apache/commons/lang/StringUtils.java?rev=594409&r1=594408&r2=594409&view=diff
==============================================================================
--- commons/proper/lang/trunk/src/java/org/apache/commons/lang/StringUtils.java (original)
+++ commons/proper/lang/trunk/src/java/org/apache/commons/lang/StringUtils.java Mon Nov 12 19:18:36 2007
@@ -69,7 +69,7 @@
* <li><b>Abbreviate</b>
* - abbreviates a string using ellipsis</li>
* <li><b>Difference</b>
- * - compares two Strings and reports on their differences</li>
+ * - compares Strings and reports on their differences</li>
* <li><b>LevensteinDistance</b>
* - the number of changes needed to change one String into another</li>
* </ul>
@@ -116,6 +116,7 @@
* @author Michael Davey
* @author Reuben Sivan
* @author Chris Hyzer
+ * @author Scott Johnson
* @since 1.0
* @version $Id$
*/
@@ -5007,6 +5008,148 @@
return -1;
}
+ /**
+ * <p>Compares all Strings in an array and returns the index at which the
+ * Strings begin to differ.</p>
+ *
+ * <p>For example,
+ * <code>indexOfDifference(new String[] {"i am a machine", "i am a robot"}) -> 7</code></p>
+ *
+ * <pre>
+ * StringUtils.indexOfDifference(null) = -1
+ * StringUtils.indexOfDifference(new String[] {}) = -1
+ * StringUtils.indexOfDifference(new String[] {"abc"}) = -1
+ * StringUtils.indexOfDifference(new String[] {null, null}) = -1
+ * StringUtils.indexOfDifference(new String[] {"", ""}) = -1
+ * StringUtils.indexOfDifference(new String[] {"", null}) = 0
+ * StringUtils.indexOfDifference(new String[] {"abc", null, null}) = 0
+ * StringUtils.indexOfDifference(new String[] {null, null, "abc"}) = 0
+ * StringUtils.indexOfDifference(new String[] {"", "abc"}) = 0
+ * StringUtils.indexOfDifference(new String[] {"abc", ""}) = 0
+ * StringUtils.indexOfDifference(new String[] {"abc", "abc"}) = -1
+ * StringUtils.indexOfDifference(new String[] {"abc", "a"}) = 1
+ * StringUtils.indexOfDifference(new String[] {"ab", "abxyz"}) = 2
+ * StringUtils.indexOfDifference(new String[] {"abcde", "abxyz"}) = 2
+ * StringUtils.indexOfDifference(new String[] {"abcde", "xyz"}) = 0
+ * StringUtils.indexOfDifference(new String[] {"xyz", "abcde"}) = 0
+ * StringUtils.indexOfDifference(new String[] {"i am a machine", "i am a robot"}) = 7
+ * </pre>
+ *
+ * @param strs array of strings, entries may be null
+ * @return the index where the strings begin to differ; -1 if they are all equal
+ */
+ public static int indexOfDifference(String[] strs) {
+ if (strs == null || strs.length <= 1) {
+ return -1;
+ }
+ boolean anyStringNull = false;
+ boolean allStringsNull = true;
+ int arrayLen = strs.length;
+ int shortestStrLen = Integer.MAX_VALUE;
+ int longestStrLen = 0;
+
+ // find the min and max string lengths; this avoids checking to make
+ // sure we are not exceeding the length of the string each time through
+ // the bottom loop.
+ for (int i=0; i<arrayLen; i++) {
+ if (strs[i] == null) {
+ anyStringNull = true;
+ shortestStrLen = 0;
+ } else {
+ allStringsNull = false;
+ shortestStrLen = Math.min(strs[i].length(), shortestStrLen);
+ longestStrLen = Math.max(strs[i].length(), longestStrLen);
+ }
+ }
+
+ // handle lists containing all nulls or all empty strings
+ if (allStringsNull || (longestStrLen == 0 && !anyStringNull)) {
+ return -1;
+ }
+
+ // handle lists containing some nulls or some empty strings
+ if (shortestStrLen == 0) {
+ return 0;
+ }
+
+ // find the position with the first difference across all strings
+ int firstDiff = -1;
+ for (int stringPos = 0; stringPos<shortestStrLen; stringPos++) {
+ char comparisonChar = strs[0].charAt(stringPos);
+ for (int arrayPos = 1; arrayPos<arrayLen; arrayPos++) {
+ if (strs[arrayPos].charAt(stringPos) != comparisonChar) {
+ firstDiff = stringPos;
+ break;
+ }
+ }
+ if (firstDiff != -1) {
+ break;
+ }
+ }
+
+ if (firstDiff == -1 && shortestStrLen != longestStrLen) {
+ // we compared all of the characters up to the length of the
+ // shortest string and didn't find a match, but the string lengths
+ // vary, so return the length of the shortest string.
+ return shortestStrLen;
+ } else {
+ return firstDiff;
+ }
+ }
+
+ /**
+ * <p>Compares all Strings in an array and returns the initial sequence of
+ * characters that is common to all of them.</p>
+ *
+ * <p>For example,
+ * <code>getCommonPrefix(new String[] {"i am a machine", "i am a robot"}) -> "i am a "</code></p>
+ *
+ * <pre>
+ * StringUtils.getCommonPrefix(null) = ""
+ * StringUtils.getCommonPrefix(new String[] {}) = ""
+ * StringUtils.getCommonPrefix(new String[] {"abc"}) = "abc"
+ * StringUtils.getCommonPrefix(new String[] {null, null}) = ""
+ * StringUtils.getCommonPrefix(new String[] {"", ""}) = ""
+ * StringUtils.getCommonPrefix(new String[] {"", null}) = ""
+ * StringUtils.getCommonPrefix(new String[] {"abc", null, null}) = ""
+ * StringUtils.getCommonPrefix(new String[] {null, null, "abc"}) = ""
+ * StringUtils.getCommonPrefix(new String[] {"", "abc"}) = ""
+ * StringUtils.getCommonPrefix(new String[] {"abc", ""}) = ""
+ * StringUtils.getCommonPrefix(new String[] {"abc", "abc"}) = "abc"
+ * StringUtils.getCommonPrefix(new String[] {"abc", "a"}) = "a"
+ * StringUtils.getCommonPrefix(new String[] {"ab", "abxyz"}) = "ab"
+ * StringUtils.getCommonPrefix(new String[] {"abcde", "abxyz"}) = "ab"
+ * StringUtils.getCommonPrefix(new String[] {"abcde", "xyz"}) = ""
+ * StringUtils.getCommonPrefix(new String[] {"xyz", "abcde"}) = ""
+ * StringUtils.getCommonPrefix(new String[] {"i am a machine", "i am a robot"}) = "i am a "
+ * </pre>
+ *
+ * @param strs array of String objects, entries may be null
+ * @return the initial sequence of characters that are common to all Strings
+ * in the array; empty String if the array is null or the strings in the
+ * array are all null; -1 if all Strings are equal
+ */
+ public static String getCommonPrefix(String[] strs) {
+ if (strs == null || strs.length == 0) {
+ return EMPTY;
+ }
+ int smallestIndexOfDiff = indexOfDifference(strs);
+ if (smallestIndexOfDiff == -1) {
+ // all strings were identical
+ if (strs[0] == null) {
+ return EMPTY;
+ } else {
+ return strs[0];
+ }
+ } else if (smallestIndexOfDiff == 0) {
+ // there were no common initial characters
+ return EMPTY;
+ } else {
+ // we found a common initial character sequence
+ return strs[0].substring(0, smallestIndexOfDiff);
+ }
+ }
+
// Misc
//-----------------------------------------------------------------------
/**
Modified: commons/proper/lang/trunk/src/test/org/apache/commons/lang/StringUtilsTest.java
URL: http://svn.apache.org/viewvc/commons/proper/lang/trunk/src/test/org/apache/commons/lang/StringUtilsTest.java?rev=594409&r1=594408&r2=594409&view=diff
==============================================================================
--- commons/proper/lang/trunk/src/test/org/apache/commons/lang/StringUtilsTest.java (original)
+++ commons/proper/lang/trunk/src/test/org/apache/commons/lang/StringUtilsTest.java Mon Nov 12 19:18:36 2007
@@ -39,6 +39,7 @@
* @author <a href="hps@intermeta.de">Henning P. Schmiedehausen</a>
* @author Phil Steitz
* @author Gary D. Gregory
+ * @author Scott Johnson
* @author Al Chou
* @version $Id$
*/
@@ -1619,4 +1620,45 @@
assertEquals("queued", StringUtils.remove("queued", 'z'));
}
+
+ public void testDifferenceAt_StringArray(){
+ assertEquals(-1, StringUtils.indexOfDifference(null));
+ assertEquals(-1, StringUtils.indexOfDifference(new String[] {}));
+ assertEquals(-1, StringUtils.indexOfDifference(new String[] {"abc"}));
+ assertEquals(-1, StringUtils.indexOfDifference(new String[] {null, null}));
+ assertEquals(-1, StringUtils.indexOfDifference(new String[] {"", ""}));
+ assertEquals(0, StringUtils.indexOfDifference(new String[] {"", null}));
+ assertEquals(0, StringUtils.indexOfDifference(new String[] {"abc", null, null}));
+ assertEquals(0, StringUtils.indexOfDifference(new String[] {null, null, "abc"}));
+ assertEquals(0, StringUtils.indexOfDifference(new String[] {"", "abc"}));
+ assertEquals(0, StringUtils.indexOfDifference(new String[] {"abc", ""}));
+ assertEquals(-1, StringUtils.indexOfDifference(new String[] {"abc", "abc"}));
+ assertEquals(1, StringUtils.indexOfDifference(new String[] {"abc", "a"}));
+ assertEquals(2, StringUtils.indexOfDifference(new String[] {"ab", "abxyz"}));
+ assertEquals(2, StringUtils.indexOfDifference(new String[] {"abcde", "abxyz"}));
+ assertEquals(0, StringUtils.indexOfDifference(new String[] {"abcde", "xyz"}));
+ assertEquals(0, StringUtils.indexOfDifference(new String[] {"xyz", "abcde"}));
+ assertEquals(7, StringUtils.indexOfDifference(new String[] {"i am a machine", "i am a robot"}));
+ }
+
+ public void testGetCommonPrefix_StringArray(){
+ assertEquals("", StringUtils.getCommonPrefix(null));
+ assertEquals("", StringUtils.getCommonPrefix(new String[] {}));
+ assertEquals("abc", StringUtils.getCommonPrefix(new String[] {"abc"}));
+ assertEquals("", StringUtils.getCommonPrefix(new String[] {null, null}));
+ assertEquals("", StringUtils.getCommonPrefix(new String[] {"", ""}));
+ assertEquals("", StringUtils.getCommonPrefix(new String[] {"", null}));
+ assertEquals("", StringUtils.getCommonPrefix(new String[] {"abc", null, null}));
+ assertEquals("", StringUtils.getCommonPrefix(new String[] {null, null, "abc"}));
+ assertEquals("", StringUtils.getCommonPrefix(new String[] {"", "abc"}));
+ assertEquals("", StringUtils.getCommonPrefix(new String[] {"abc", ""}));
+ assertEquals("abc", StringUtils.getCommonPrefix(new String[] {"abc", "abc"}));
+ assertEquals("a", StringUtils.getCommonPrefix(new String[] {"abc", "a"}));
+ assertEquals("ab", StringUtils.getCommonPrefix(new String[] {"ab", "abxyz"}));
+ assertEquals("ab", StringUtils.getCommonPrefix(new String[] {"abcde", "abxyz"}));
+ assertEquals("", StringUtils.getCommonPrefix(new String[] {"abcde", "xyz"}));
+ assertEquals("", StringUtils.getCommonPrefix(new String[] {"xyz", "abcde"}));
+ assertEquals("i am a ", StringUtils.getCommonPrefix(new String[] {"i am a machine", "i am a robot"}));
+ }
+
}