diff --git a/src/main/java/org/apache/commons/lang3/ArrayUtils.java b/src/main/java/org/apache/commons/lang3/ArrayUtils.java index 244ed6bbb..e4ff2676c 100644 --- a/src/main/java/org/apache/commons/lang3/ArrayUtils.java +++ b/src/main/java/org/apache/commons/lang3/ArrayUtils.java @@ -5020,7 +5020,7 @@ public static T[] removeElements(T[] array, T... values) { } } @SuppressWarnings("unchecked") // removeAll() always creates an array of the same type as its input - T[] result = (T[]) removeAll((Object)array, extractIndices(toRemove)); + T[] result = (T[]) removeAll(array, toRemove); return result; } @@ -5110,7 +5110,7 @@ public static byte[] removeElements(byte[] array, byte... values) { toRemove.set(found++); } } - return (byte[]) removeAll((Object)array, extractIndices(toRemove)); + return (byte[]) removeAll(array, toRemove); } /** @@ -5199,7 +5199,7 @@ public static short[] removeElements(short[] array, short... values) { toRemove.set(found++); } } - return (short[]) removeAll((Object)array, extractIndices(toRemove)); + return (short[]) removeAll(array, toRemove); } /** @@ -5288,7 +5288,7 @@ public static int[] removeElements(int[] array, int... values) { toRemove.set(found++); } } - return (int[]) removeAll((Object)array, extractIndices(toRemove)); + return (int[]) removeAll(array, toRemove); } /** @@ -5377,7 +5377,7 @@ public static char[] removeElements(char[] array, char... values) { toRemove.set(found++); } } - return (char[]) removeAll((Object)array, extractIndices(toRemove)); + return (char[]) removeAll(array, toRemove); } /** @@ -5466,7 +5466,7 @@ public static long[] removeElements(long[] array, long... values) { toRemove.set(found++); } } - return (long[]) removeAll((Object)array, extractIndices(toRemove)); + return (long[]) removeAll(array, toRemove); } /** @@ -5555,7 +5555,7 @@ public static float[] removeElements(float[] array, float... values) { toRemove.set(found++); } } - return (float[]) removeAll((Object)array, extractIndices(toRemove)); + return (float[]) removeAll(array, toRemove); } /** @@ -5644,7 +5644,7 @@ public static double[] removeElements(double[] array, double... values) { toRemove.set(found++); } } - return (double[]) removeAll((Object)array, extractIndices(toRemove)); + return (double[]) removeAll(array, toRemove); } /** @@ -5729,7 +5729,7 @@ public static boolean[] removeElements(boolean[] array, boolean... values) { toRemove.set(found++); } } - return (boolean[]) removeAll((Object)array, extractIndices(toRemove)); + return (boolean[]) removeAll(array, toRemove); } /** @@ -5783,16 +5783,39 @@ static Object removeAll(Object array, int... indices) { } /** - * Extract a set of BitSet indices into an int[]. - * @param coll Bitset - * @return int[] + * Removes multiple array elements specified by indices. + * + * @param array source + * @param indices to remove + * @return new array of same type minus elements specified by the set bits in {@code indices} + * @since 3.2 */ - private static int[] extractIndices(BitSet coll) { - int[] result = new int[coll.cardinality()]; - int i = 0; - int j=0; - while((j=coll.nextSetBit(j)) != -1) { - result[i++] = j++; + // package protected for access by unit tests + static Object removeAll(Object array, BitSet indices) { + final int srcLength = ArrayUtils.getLength(array); + // No need to check maxIndex here, because method only currently called from removeElements() + // which guarantee to generate on;y valid bit entries. +// final int maxIndex = indices.length(); +// if (maxIndex > srcLength) { +// throw new IndexOutOfBoundsException("Index: " + (maxIndex-1) + ", Length: " + srcLength); +// } + final int removals = indices.cardinality(); // true bits are items to remove + Object result = Array.newInstance(array.getClass().getComponentType(), srcLength - removals); + int srcIndex=0; + int destIndex=0; + int count; + int set; + while((set = indices.nextSetBit(srcIndex)) != -1){ + count = set - srcIndex; + if (count > 0) { + System.arraycopy(array, srcIndex, result, destIndex, count); + destIndex += count; + } + srcIndex = indices.nextClearBit(set); + } + count = srcLength - srcIndex; + if (count > 0) { + System.arraycopy(array, srcIndex, result, destIndex, count); } return result; } diff --git a/src/test/java/org/apache/commons/lang3/HashSetvBitSetTest.java b/src/test/java/org/apache/commons/lang3/HashSetvBitSetTest.java index 00f0c5060..394c77355 100644 --- a/src/test/java/org/apache/commons/lang3/HashSetvBitSetTest.java +++ b/src/test/java/org/apache/commons/lang3/HashSetvBitSetTest.java @@ -16,7 +16,6 @@ */ package org.apache.commons.lang3; -import java.lang.reflect.Array; import java.util.BitSet; import java.util.HashSet; @@ -146,7 +145,7 @@ private long timeBitSetRemoveAll(int[] array, BitSet toRemove) { int[] output = new int[0]; long start = System.nanoTime(); for(int i = 0; i < LOOPS2; i++){ - output = (int[]) removeAll(array, toRemove); + output = (int[]) ArrayUtils.removeAll(array, toRemove); } long end = System.nanoTime(); Assert.assertEquals(array.length-toRemove.cardinality(), output.length); @@ -165,39 +164,4 @@ private long timeExtractRemoveAll(int[] array, BitSet toRemove) { return end - start; } - /** - * Removes multiple array elements specified by indices. - * - * @param array source - * @param indices to remove - * @return new array of same type minus elements specified by the set bits in {@code indices} - * @since 3.2 - */ - // package protected for access by unit tests - static Object removeAll(Object array, BitSet indices) { - final int srcLength = ArrayUtils.getLength(array); - final int maxIndex = indices.length(); - if (maxIndex > srcLength) { // TODO necessary? Can check this when creating the BitSit - throw new IndexOutOfBoundsException("Index: " + (maxIndex-1) + ", Length: " + srcLength); - } - final int removals = indices.cardinality(); // true bits are items to remove - Object result = Array.newInstance(array.getClass().getComponentType(), srcLength - removals); - int srcIndex=0; - int destIndex=0; - int count; - int set; - while((set = indices.nextSetBit(srcIndex)) != -1){ - count = set - srcIndex; - if (count > 0) { - System.arraycopy(array, srcIndex, result, destIndex, count); - destIndex += count; - } - srcIndex = indices.nextClearBit(set); - } - count = srcLength - srcIndex; - if (count > 0) { - System.arraycopy(array, srcIndex, result, destIndex, count); - } - return result; - } } \ No newline at end of file