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
This commit is contained in:
Duncan Jones 2014-10-19 05:52:37 +00:00
parent 09cee6a4ad
commit ef26a66763
10 changed files with 574 additions and 12 deletions

View File

@ -373,6 +373,9 @@
<contributor>
<name>Scott Sanders</name>
</contributor>
<contributor>
<name>James Sawle</name>
</contributor>
<contributor>
<name>Ralph Schaer</name>
</contributor>

View File

@ -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>

View File

@ -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 @@ public static byte[] removeElements(final byte[] array, final byte... values) {
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 @@ static Object removeAll(final Object array, final BitSet indices) {
}
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;
}
}

View File

@ -1085,4 +1085,25 @@ public static Boolean xor(final Boolean... array) {
}
}
/**
* <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;
}
}
}

View File

@ -535,5 +535,18 @@ public static boolean isAsciiNumeric(final char ch) {
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;
}
}

View File

@ -1495,4 +1495,80 @@ public static boolean isParsable(final String str) {
}
}
/**
* <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;
}
}

View File

@ -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 @@ public void testGetLength() {
} 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));
}
}

View File

@ -1006,5 +1006,13 @@ public void testOr_object_validInput_3items() {
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);
}
}

View File

@ -354,5 +354,11 @@ public void testIsAsciiAlphanumeric_char() {
}
}
}
@Test
public void testCompare() {
assertTrue(CharUtils.compare('a', 'b') < 0);
assertTrue(CharUtils.compare('c', 'c') == 0);
assertTrue(CharUtils.compare('c', 'a') > 0);
}
}

View File

@ -1359,4 +1359,31 @@ public void testLang381() {
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);
}
}