LANG-839 ArrayUtils removeElements methods use unnecessary HashSet

Eliminate conversion of BitSet to int[]

git-svn-id: https://svn.apache.org/repos/asf/commons/proper/lang/trunk@1396075 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Sebastian Bazley 2012-10-09 15:37:05 +00:00
parent 49685a4156
commit 8bbf8a9e2f
2 changed files with 42 additions and 55 deletions

View File

@ -5020,7 +5020,7 @@ public class ArrayUtils {
} }
} }
@SuppressWarnings("unchecked") // removeAll() always creates an array of the same type as its input @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; return result;
} }
@ -5110,7 +5110,7 @@ public class ArrayUtils {
toRemove.set(found++); toRemove.set(found++);
} }
} }
return (byte[]) removeAll((Object)array, extractIndices(toRemove)); return (byte[]) removeAll(array, toRemove);
} }
/** /**
@ -5199,7 +5199,7 @@ public class ArrayUtils {
toRemove.set(found++); toRemove.set(found++);
} }
} }
return (short[]) removeAll((Object)array, extractIndices(toRemove)); return (short[]) removeAll(array, toRemove);
} }
/** /**
@ -5288,7 +5288,7 @@ public class ArrayUtils {
toRemove.set(found++); toRemove.set(found++);
} }
} }
return (int[]) removeAll((Object)array, extractIndices(toRemove)); return (int[]) removeAll(array, toRemove);
} }
/** /**
@ -5377,7 +5377,7 @@ public class ArrayUtils {
toRemove.set(found++); toRemove.set(found++);
} }
} }
return (char[]) removeAll((Object)array, extractIndices(toRemove)); return (char[]) removeAll(array, toRemove);
} }
/** /**
@ -5466,7 +5466,7 @@ public class ArrayUtils {
toRemove.set(found++); toRemove.set(found++);
} }
} }
return (long[]) removeAll((Object)array, extractIndices(toRemove)); return (long[]) removeAll(array, toRemove);
} }
/** /**
@ -5555,7 +5555,7 @@ public class ArrayUtils {
toRemove.set(found++); toRemove.set(found++);
} }
} }
return (float[]) removeAll((Object)array, extractIndices(toRemove)); return (float[]) removeAll(array, toRemove);
} }
/** /**
@ -5644,7 +5644,7 @@ public class ArrayUtils {
toRemove.set(found++); toRemove.set(found++);
} }
} }
return (double[]) removeAll((Object)array, extractIndices(toRemove)); return (double[]) removeAll(array, toRemove);
} }
/** /**
@ -5729,7 +5729,7 @@ public class ArrayUtils {
toRemove.set(found++); toRemove.set(found++);
} }
} }
return (boolean[]) removeAll((Object)array, extractIndices(toRemove)); return (boolean[]) removeAll(array, toRemove);
} }
/** /**
@ -5783,16 +5783,39 @@ public class ArrayUtils {
} }
/** /**
* Extract a set of BitSet indices into an int[]. * Removes multiple array elements specified by indices.
* @param coll Bitset *
* @return int[] * @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) { // package protected for access by unit tests
int[] result = new int[coll.cardinality()]; static Object removeAll(Object array, BitSet indices) {
int i = 0; final int srcLength = ArrayUtils.getLength(array);
int j=0; // No need to check maxIndex here, because method only currently called from removeElements()
while((j=coll.nextSetBit(j)) != -1) { // which guarantee to generate on;y valid bit entries.
result[i++] = j++; // 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; return result;
} }

View File

@ -16,7 +16,6 @@
*/ */
package org.apache.commons.lang3; package org.apache.commons.lang3;
import java.lang.reflect.Array;
import java.util.BitSet; import java.util.BitSet;
import java.util.HashSet; import java.util.HashSet;
@ -146,7 +145,7 @@ public class HashSetvBitSetTest {
int[] output = new int[0]; int[] output = new int[0];
long start = System.nanoTime(); long start = System.nanoTime();
for(int i = 0; i < LOOPS2; i++){ for(int i = 0; i < LOOPS2; i++){
output = (int[]) removeAll(array, toRemove); output = (int[]) ArrayUtils.removeAll(array, toRemove);
} }
long end = System.nanoTime(); long end = System.nanoTime();
Assert.assertEquals(array.length-toRemove.cardinality(), output.length); Assert.assertEquals(array.length-toRemove.cardinality(), output.length);
@ -165,39 +164,4 @@ public class HashSetvBitSetTest {
return end - start; 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;
}
} }