LANG-536 - Add isSorted() to ArrayUtils. Patch supplied by James Sawle. Closes #32 in GitHub.
git-svn-id: https://svn.apache.org/repos/asf/commons/proper/lang/trunk@1632874 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/pom.xml b/pom.xml
index a5da63e..47f522c 100644
--- a/pom.xml
+++ b/pom.xml
@@ -374,6 +374,9 @@
<name>Scott Sanders</name>
</contributor>
<contributor>
+ <name>James Sawle</name>
+ </contributor>
+ <contributor>
<name>Ralph Schaer</name>
</contributor>
<contributor>
diff --git a/src/changes/changes.xml b/src/changes/changes.xml
index d2932ce..2ddb50e 100644
--- a/src/changes/changes.xml
+++ b/src/changes/changes.xml
@@ -22,6 +22,7 @@
<body>
<release version="3.4" date="tba" description="tba">
+ <action issue="LANG-536" type="add" dev="djones" due-to="James Sawle">Add isSorted() to ArrayUtils</action>
<action issue="LANG-1041" type="fix" dev="britter" due-to="Alexandre Bartel">Fix MethodUtilsTest so it does not depend on JDK method ordering</action>
<action issue="LANG-827" type="update" dev="djones">CompareToBuilder's doc doesn't specify precedence of fields it uses in performing comparisons</action>
<action issue="LANG-1000" type="fix" dev="djones">ParseException when trying to parse UTC dates with Z as zone designator using DateFormatUtils.ISO_DATETIME_TIME_ZONE_FORMAT</action>
diff --git a/src/main/java/org/apache/commons/lang3/ArrayUtils.java b/src/main/java/org/apache/commons/lang3/ArrayUtils.java
index 06fb274..644c0b8 100644
--- a/src/main/java/org/apache/commons/lang3/ArrayUtils.java
+++ b/src/main/java/org/apache/commons/lang3/ArrayUtils.java
@@ -19,6 +19,7 @@
import java.lang.reflect.Array;
import java.util.Arrays;
import java.util.BitSet;
+import java.util.Comparator;
import java.util.HashMap;
import java.util.Map;
@@ -26,6 +27,7 @@
import org.apache.commons.lang3.builder.HashCodeBuilder;
import org.apache.commons.lang3.builder.ToStringBuilder;
import org.apache.commons.lang3.builder.ToStringStyle;
+import org.apache.commons.lang3.math.NumberUtils;
import org.apache.commons.lang3.mutable.MutableInt;
/**
@@ -5356,7 +5358,7 @@
if (isEmpty(array) || isEmpty(values)) {
return clone(array);
}
- final HashMap<Byte, MutableInt> occurrences = new HashMap<Byte, MutableInt>(values.length);
+ final Map<Byte, MutableInt> occurrences = new HashMap<Byte, MutableInt>(values.length);
for (final byte v : values) {
final Byte boxed = Byte.valueOf(v);
final MutableInt count = occurrences.get(boxed);
@@ -6087,4 +6089,255 @@
}
return result;
}
+
+ /**
+ * <p>This method checks whether the provided array is sorted according to the class's
+ * {@code compareTo} method.</p>
+ *
+ * @param array the array to check
+ * @param <T> the datatype of the array to check, it must implement {@code Comparable}
+ * @return whether the array is sorted
+ * @since 3.4
+ */
+ public static <T extends Comparable<? super T>> boolean isSorted(final T[] array) {
+ return isSorted(array, new Comparator<T>() {
+ @Override
+ public int compare(T o1, T o2) {
+ return o1.compareTo(o2);
+ }
+ });
+ }
+
+
+ /**
+ * <p>This method checks whether the provided array is sorted according to the provided {@code Comparator}.</p>
+ *
+ * @param array the array to check
+ * @param comparator the {@code Comparator} to compare over
+ * @param <T> the datatype of the array
+ * @return whether the array is sorted
+ * @since 3.4
+ */
+ public static <T> boolean isSorted(final T[] array, final Comparator<T> comparator) {
+ if (comparator == null) {
+ throw new IllegalArgumentException("Comparator should not be null.");
+ }
+
+ if(array == null || array.length < 2) {
+ return true;
+ }
+
+ T previous = array[0];
+ final int n = array.length;
+ for(int i = 1; i < n; i++) {
+ final T current = array[i];
+ if (comparator.compare(previous, current) > 0) {
+ return false;
+ }
+
+ previous = current;
+ }
+ return true;
+ }
+
+ /**
+ * <p>This method checks whether the provided array is sorted according to natural ordering.</p>
+ *
+ * @param array the array to check
+ * @return whether the array is sorted according to natural ordering
+ * @since 3.4
+ */
+ public static boolean isSorted(int[] array) {
+ if(array == null || array.length < 2) {
+ return true;
+ }
+
+ int previous = array[0];
+ final int n = array.length;
+ for(int i = 1; i < n; i++) {
+ final int current = array[i];
+ if(NumberUtils.compare(previous, current) > 0) {
+ return false;
+ }
+
+ previous = current;
+ }
+ return true;
+ }
+
+ /**
+ * <p>This method checks whether the provided array is sorted according to natural ordering.</p>
+ *
+ * @param array the array to check
+ * @return whether the array is sorted according to natural ordering
+ * @since 3.4
+ */
+ public static boolean isSorted(long[] array) {
+ if(array == null || array.length < 2) {
+ return true;
+ }
+
+ long previous = array[0];
+ final int n = array.length;
+ for(int i = 1; i < n; i++) {
+ final long current = array[i];
+ if(NumberUtils.compare(previous, current) > 0) {
+ return false;
+ }
+
+ previous = current;
+ }
+ return true;
+ }
+
+ /**
+ * <p>This method checks whether the provided array is sorted according to natural ordering.</p>
+ *
+ * @param array the array to check
+ * @return whether the array is sorted according to natural ordering
+ * @since 3.4
+ */
+ public static boolean isSorted(short[] array) {
+ if(array == null || array.length < 2) {
+ return true;
+ }
+
+ short previous = array[0];
+ final int n = array.length;
+ for(int i = 1; i < n; i++) {
+ final short current = array[i];
+ if(NumberUtils.compare(previous, current) > 0) {
+ return false;
+ }
+
+ previous = current;
+ }
+ return true;
+ }
+
+ /**
+ * <p>This method checks whether the provided array is sorted according to natural ordering.</p>
+ *
+ * @param array the array to check
+ * @return whether the array is sorted according to natural ordering
+ * @since 3.4
+ */
+ public static boolean isSorted(final double[] array) {
+ if(array == null || array.length < 2) {
+ return true;
+ }
+
+ double previous = array[0];
+ final int n = array.length;
+ for(int i = 1; i < n; i++) {
+ final double current = array[i];
+ if(Double.compare(previous, current) > 0) {
+ return false;
+ }
+
+ previous = current;
+ }
+ return true;
+ }
+
+ /**
+ * <p>This method checks whether the provided array is sorted according to natural ordering.</p>
+ *
+ * @param array the array to check
+ * @return whether the array is sorted according to natural ordering
+ * @since 3.4
+ */
+ public static boolean isSorted(final float[] array) {
+ if(array == null || array.length < 2) {
+ return true;
+ }
+
+ float previous = array[0];
+ final int n = array.length;
+ for(int i = 1; i < n; i++) {
+ final float current = array[i];
+ if(Float.compare(previous, current) > 0) {
+ return false;
+ }
+
+ previous = current;
+ }
+ return true;
+ }
+
+ /**
+ * <p>This method checks whether the provided array is sorted according to natural ordering.</p>
+ *
+ * @param array the array to check
+ * @return whether the array is sorted according to natural ordering
+ * @since 3.4
+ */
+ public static boolean isSorted(byte[] array) {
+ if(array == null || array.length < 2) {
+ return true;
+ }
+
+ byte previous = array[0];
+ final int n = array.length;
+ for(int i = 1; i < n; i++) {
+ final byte current = array[i];
+ if(NumberUtils.compare(previous, current) > 0) {
+ return false;
+ }
+
+ previous = current;
+ }
+ return true;
+ }
+
+ /**
+ * <p>This method checks whether the provided array is sorted according to natural ordering.</p>
+ *
+ * @param array the array to check
+ * @return whether the array is sorted according to natural ordering
+ * @since 3.4
+ */
+ public static boolean isSorted(char[] array) {
+ if(array == null || array.length < 2) {
+ return true;
+ }
+
+ char previous = array[0];
+ final int n = array.length;
+ for(int i = 1; i < n; i++) {
+ final char current = array[i];
+ if(CharUtils.compare(previous, current) > 0) {
+ return false;
+ }
+
+ previous = current;
+ }
+ return true;
+ }
+
+ /**
+ * <p>This method checks whether the provided array is sorted according to natural ordering
+ * ({@code false} before {@code true}).</p>
+ *
+ * @param array the array to check
+ * @return whether the array is sorted according to natural ordering
+ * @since 3.4
+ */
+ public static boolean isSorted(boolean[] array) {
+ if(array == null || array.length < 2) {
+ return true;
+ }
+
+ boolean previous = array[0];
+ final int n = array.length;
+ for(int i = 1; i < n; i++) {
+ final boolean current = array[i];
+ if(BooleanUtils.compare(previous, current) > 0) {
+ return false;
+ }
+
+ previous = current;
+ }
+ return true;
+ }
}
diff --git a/src/main/java/org/apache/commons/lang3/BooleanUtils.java b/src/main/java/org/apache/commons/lang3/BooleanUtils.java
index fcbad66..1832fe0 100644
--- a/src/main/java/org/apache/commons/lang3/BooleanUtils.java
+++ b/src/main/java/org/apache/commons/lang3/BooleanUtils.java
@@ -1085,4 +1085,25 @@
}
}
+ /**
+ * <p>Compares two {@code boolean} values. This is the same functionality as provided in Java 7.</p>
+ *
+ * @param x the first {@code boolean} to compare
+ * @param y the second {@code boolean} to compare
+ * @return the value {@code 0} if {@code x == y};
+ * a value less than {@code 0} if {@code !x && y}; and
+ * a value greater than {@code 0} if {@code x && !y}
+ * @since 3.4
+ */
+ public static int compare(boolean x, boolean y) {
+ if (x == y) {
+ return 0;
+ }
+ if (x) {
+ return 1;
+ } else {
+ return -1;
+ }
+ }
+
}
diff --git a/src/main/java/org/apache/commons/lang3/CharUtils.java b/src/main/java/org/apache/commons/lang3/CharUtils.java
index f8f284e..3f19a21 100644
--- a/src/main/java/org/apache/commons/lang3/CharUtils.java
+++ b/src/main/java/org/apache/commons/lang3/CharUtils.java
@@ -535,5 +535,18 @@
public static boolean isAsciiAlphanumeric(final char ch) {
return isAsciiAlpha(ch) || isAsciiNumeric(ch);
}
-
+
+ /**
+ * <p>Compares two {@code char} values numerically. This is the same functionality as provided in Java 7.</p>
+ *
+ * @param x the first {@code char} to compare
+ * @param y the second {@code char} to compare
+ * @return the value {@code 0} if {@code x == y};
+ * a value less than {@code 0} if {@code x < y}; and
+ * a value greater than {@code 0} if {@code x > y}
+ * @since 3.4
+ */
+ public static int compare(char x, char y) {
+ return x-y;
+ }
}
diff --git a/src/main/java/org/apache/commons/lang3/math/NumberUtils.java b/src/main/java/org/apache/commons/lang3/math/NumberUtils.java
index 9eaf57d..14f4bf4 100644
--- a/src/main/java/org/apache/commons/lang3/math/NumberUtils.java
+++ b/src/main/java/org/apache/commons/lang3/math/NumberUtils.java
@@ -1495,4 +1495,80 @@
}
}
+ /**
+ * <p>Compares two {@code int} values numerically. This is the same functionality as provided in Java 7.</p>
+ *
+ * @param x the first {@code int} to compare
+ * @param y the second {@code int} to compare
+ * @return the value {@code 0} if {@code x == y};
+ * a value less than {@code 0} if {@code x < y}; and
+ * a value greater than {@code 0} if {@code x > y}
+ * @since 3.4
+ */
+ public static int compare(int x, int y) {
+ if (x == y) {
+ return 0;
+ }
+ if (x < y) {
+ return -1;
+ } else {
+ return 1;
+ }
+ }
+
+ /**
+ * <p>Compares to {@code long} values numerically. This is the same functionality as provided in Java 7.</p>
+ *
+ * @param x the first {@code long} to compare
+ * @param y the second {@code long} to compare
+ * @return the value {@code 0} if {@code x == y};
+ * a value less than {@code 0} if {@code x < y}; and
+ * a value greater than {@code 0} if {@code x > y}
+ * @since 3.4
+ */
+ public static int compare(long x, long y) {
+ if (x == y) {
+ return 0;
+ }
+ if (x < y) {
+ return -1;
+ } else {
+ return 1;
+ }
+ }
+
+ /**
+ * <p>Compares to {@code short} values numerically. This is the same functionality as provided in Java 7.</p>
+ *
+ * @param x the first {@code short} to compare
+ * @param y the second {@code short} to compare
+ * @return the value {@code 0} if {@code x == y};
+ * a value less than {@code 0} if {@code x < y}; and
+ * a value greater than {@code 0} if {@code x > y}
+ * @since 3.4
+ */
+ public static int compare(short x, short y) {
+ if (x == y) {
+ return 0;
+ }
+ if (x < y) {
+ return -1;
+ } else {
+ return 1;
+ }
+ }
+
+ /**
+ * <p>Compares two {@code byte} values numerically. This is the same functionality as provided in Java 7.</p>
+ *
+ * @param x the first {@code byte} to compare
+ * @param y the second {@code byte} to compare
+ * @return the value {@code 0} if {@code x == y};
+ * a value less than {@code 0} if {@code x < y}; and
+ * a value greater than {@code 0} if {@code x > y}
+ * @since 3.4
+ */
+ public static int compare(byte x, byte y) {
+ return x-y;
+ }
}
diff --git a/src/test/java/org/apache/commons/lang3/ArrayUtilsTest.java b/src/test/java/org/apache/commons/lang3/ArrayUtilsTest.java
index af7ceba..27150ae 100644
--- a/src/test/java/org/apache/commons/lang3/ArrayUtilsTest.java
+++ b/src/test/java/org/apache/commons/lang3/ArrayUtilsTest.java
@@ -16,19 +16,12 @@
*/
package org.apache.commons.lang3;
-import static org.junit.Assert.assertArrayEquals;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertNotSame;
-import static org.junit.Assert.assertNull;
-import static org.junit.Assert.assertSame;
-import static org.junit.Assert.assertTrue;
-import static org.junit.Assert.fail;
+import static org.junit.Assert.*;
import java.lang.reflect.Constructor;
import java.lang.reflect.Modifier;
import java.util.Arrays;
+import java.util.Comparator;
import java.util.Date;
import java.util.Map;
@@ -3472,4 +3465,165 @@
} catch (final IllegalArgumentException e) {}
}
+ @Test
+ public void testIsSorted() {
+ Integer[] array = null;
+ assertTrue(ArrayUtils.isSorted(array));
+
+ array = new Integer[]{1};
+ assertTrue(ArrayUtils.isSorted(array));
+
+ array = new Integer[]{1,2,3};
+ assertTrue(ArrayUtils.isSorted(array));
+
+ array = new Integer[]{1,3,2};
+ assertFalse(ArrayUtils.isSorted(array));
+ }
+
+ @Test
+ public void testIsSortedComparator() {
+ Comparator<Integer> c = new Comparator<Integer>() {
+ public int compare(Integer o1, Integer o2) {
+ return o2.compareTo(o1);
+ }
+ };
+
+ Integer[] array = null;
+ assertTrue(ArrayUtils.isSorted(array, c));
+
+ array = new Integer[]{1};
+ assertTrue(ArrayUtils.isSorted(array, c));
+
+ array = new Integer[]{3,2,1};
+ assertTrue(ArrayUtils.isSorted(array, c));
+
+ array = new Integer[]{1,3,2};
+ assertFalse(ArrayUtils.isSorted(array, c));
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void testIsSortedNullComparator() throws Exception {
+ ArrayUtils.isSorted(null, null);
+ }
+
+ @Test
+ public void testIsSortedInt() {
+ int[] array = null;
+ assertTrue(ArrayUtils.isSorted(array));
+
+ array = new int[]{1};
+ assertTrue(ArrayUtils.isSorted(array));
+
+ array = new int[]{1,2,3};
+ assertTrue(ArrayUtils.isSorted(array));
+
+ array = new int[]{1,3,2};
+ assertFalse(ArrayUtils.isSorted(array));
+ }
+
+ @Test
+ public void testIsSortedFloat() {
+ float[] array = null;
+ assertTrue(ArrayUtils.isSorted(array));
+
+ array = new float[]{0f};
+ assertTrue(ArrayUtils.isSorted(array));
+
+ array = new float[]{-1f, 0f, 0.1f, 0.2f};
+ assertTrue(ArrayUtils.isSorted(array));
+
+ array = new float[]{-1f, 0.2f, 0.1f, 0f};
+ assertFalse(ArrayUtils.isSorted(array));
+ }
+
+ @Test
+ public void testIsSortedLong() {
+ long[] array = null;
+ assertTrue(ArrayUtils.isSorted(array));
+
+ array = new long[]{0L};
+ assertTrue(ArrayUtils.isSorted(array));
+
+ array = new long[]{-1L, 0L, 1L};
+ assertTrue(ArrayUtils.isSorted(array));
+
+ array = new long[]{-1L, 1L, 0L};
+ assertFalse(ArrayUtils.isSorted(array));
+ }
+
+ @Test
+ public void testIsSortedDouble() {
+ double[] array = null;
+ assertTrue(ArrayUtils.isSorted(array));
+
+ array = new double[]{0.0};
+ assertTrue(ArrayUtils.isSorted(array));
+
+ array = new double[]{-1.0, 0.0, 0.1, 0.2};
+ assertTrue(ArrayUtils.isSorted(array));
+
+ array = new double[]{-1.0, 0.2, 0.1, 0.0};
+ assertFalse(ArrayUtils.isSorted(array));
+ }
+
+ @Test
+ public void testIsSortedChar() {
+ char[] array = null;
+ assertTrue(ArrayUtils.isSorted(array));
+
+ array = new char[]{'a'};
+ assertTrue(ArrayUtils.isSorted(array));
+
+ array = new char[]{'a', 'b', 'c'};
+ assertTrue(ArrayUtils.isSorted(array));
+
+ array = new char[]{'a', 'c', 'b'};
+ assertFalse(ArrayUtils.isSorted(array));
+ }
+
+ @Test
+ public void testIsSortedByte() {
+ byte[] array = null;
+ assertTrue(ArrayUtils.isSorted(array));
+
+ array = new byte[]{0x10};
+ assertTrue(ArrayUtils.isSorted(array));
+
+ array = new byte[]{0x10, 0x20, 0x30};
+ assertTrue(ArrayUtils.isSorted(array));
+
+ array = new byte[]{0x10, 0x30, 0x20};
+ assertFalse(ArrayUtils.isSorted(array));
+ }
+
+ @Test
+ public void testIsSortedShort() {
+ short[] array = null;
+ assertTrue(ArrayUtils.isSorted(array));
+
+ array = new short[]{0};
+ assertTrue(ArrayUtils.isSorted(array));
+
+ array = new short[]{-1, 0, 1};
+ assertTrue(ArrayUtils.isSorted(array));
+
+ array = new short[]{-1, 1, 0};
+ assertFalse(ArrayUtils.isSorted(array));
+ }
+
+ @Test
+ public void testIsSortedBool() {
+ boolean[] array = null;
+ assertTrue(ArrayUtils.isSorted(array));
+
+ array = new boolean[]{true};
+ assertTrue(ArrayUtils.isSorted(array));
+
+ array = new boolean[]{false, true};
+ assertTrue(ArrayUtils.isSorted(array));
+
+ array = new boolean[]{true, false};
+ assertFalse(ArrayUtils.isSorted(array));
+ }
+
}
diff --git a/src/test/java/org/apache/commons/lang3/BooleanUtilsTest.java b/src/test/java/org/apache/commons/lang3/BooleanUtilsTest.java
index f157080..d3464b7 100644
--- a/src/test/java/org/apache/commons/lang3/BooleanUtilsTest.java
+++ b/src/test/java/org/apache/commons/lang3/BooleanUtilsTest.java
@@ -1006,5 +1006,13 @@
Boolean.TRUE })
.booleanValue());
}
+
+ @Test
+ public void testCompare(){
+ assertTrue(BooleanUtils.compare(true, false) > 0);
+ assertTrue(BooleanUtils.compare(true, true) == 0);
+ assertTrue(BooleanUtils.compare(false, false) == 0);
+ assertTrue(BooleanUtils.compare(false, true) < 0);
+ }
}
diff --git a/src/test/java/org/apache/commons/lang3/CharUtilsTest.java b/src/test/java/org/apache/commons/lang3/CharUtilsTest.java
index b2adcb3..94acbcd 100644
--- a/src/test/java/org/apache/commons/lang3/CharUtilsTest.java
+++ b/src/test/java/org/apache/commons/lang3/CharUtilsTest.java
@@ -354,5 +354,11 @@
}
}
}
-
+
+ @Test
+ public void testCompare() {
+ assertTrue(CharUtils.compare('a', 'b') < 0);
+ assertTrue(CharUtils.compare('c', 'c') == 0);
+ assertTrue(CharUtils.compare('c', 'a') > 0);
+ }
}
diff --git a/src/test/java/org/apache/commons/lang3/math/NumberUtilsTest.java b/src/test/java/org/apache/commons/lang3/math/NumberUtilsTest.java
index e9ec47d..e40293c 100644
--- a/src/test/java/org/apache/commons/lang3/math/NumberUtilsTest.java
+++ b/src/test/java/org/apache/commons/lang3/math/NumberUtilsTest.java
@@ -1359,4 +1359,31 @@
assertTrue(Float.isNaN(NumberUtils.max(bF)));
}
+ @Test
+ public void compareInt() {
+ assertTrue(NumberUtils.compare(-3, 0) < 0);
+ assertTrue(NumberUtils.compare(113, 113)==0);
+ assertTrue(NumberUtils.compare(213, 32) > 0);
+ }
+
+ @Test
+ public void compareLong() {
+ assertTrue(NumberUtils.compare(-3L, 0L) < 0);
+ assertTrue(NumberUtils.compare(113L, 113L)==0);
+ assertTrue(NumberUtils.compare(213L, 32L) > 0);
+ }
+
+ @Test
+ public void compareShort() {
+ assertTrue(NumberUtils.compare((short)-3, (short)0) < 0);
+ assertTrue(NumberUtils.compare((short)113, (short)113)==0);
+ assertTrue(NumberUtils.compare((short)213, (short)32) > 0);
+ }
+
+ @Test
+ public void compareByte() {
+ assertTrue(NumberUtils.compare((byte)-3, (byte)0) < 0);
+ assertTrue(NumberUtils.compare((byte)113, (byte)113)==0);
+ assertTrue(NumberUtils.compare((byte)123, (byte)32) > 0);
+ }
}