Merge "Improve utility of IntArray and LongArray"

am: 35786735df

Change-Id: Id50add8d7e3fc45978752a6a31760bc69df0cc4a
This commit is contained in:
Hugo Benichi
2017-04-10 01:17:42 +00:00
committed by android-build-merger
4 changed files with 294 additions and 29 deletions

View File

@@ -17,7 +17,7 @@
package android.util;
import com.android.internal.util.ArrayUtils;
import com.android.internal.util.Preconditions;
import java.util.Arrays;
import libcore.util.EmptyArray;
@@ -32,6 +32,11 @@ public class IntArray implements Cloneable {
private int[] mValues;
private int mSize;
private IntArray(int[] array, int size) {
mValues = array;
mSize = Preconditions.checkArgumentInRange(size, 0, array.length, "size");
}
/**
* Creates an empty IntArray with the default initial capacity.
*/
@@ -51,6 +56,35 @@ public class IntArray implements Cloneable {
mSize = 0;
}
/**
* Creates an IntArray wrapping the given primitive int array.
*/
public static IntArray wrap(int[] array) {
return new IntArray(array, array.length);
}
/**
* Creates an IntArray from the given primitive int array, copying it.
*/
public static IntArray fromArray(int[] array, int size) {
return wrap(Arrays.copyOf(array, size));
}
/**
* Changes the size of this IntArray. If this IntArray is shrinked, the backing array capacity
* is unchanged. If the new size is larger than backing array capacity, a new backing array is
* created from the current content of this IntArray padded with 0s.
*/
public void resize(int newSize) {
Preconditions.checkArgumentNonnegative(newSize);
if (newSize <= mValues.length) {
Arrays.fill(mValues, newSize, mValues.length, 0);
} else {
ensureCapacity(newSize - mSize);
}
mSize = newSize;
}
/**
* Appends the specified value to the end of this array.
*/
@@ -59,23 +93,23 @@ public class IntArray implements Cloneable {
}
/**
* Inserts a value at the specified position in this array.
* Inserts a value at the specified position in this array. If the specified index is equal to
* the length of the array, the value is added at the end.
*
* @throws IndexOutOfBoundsException when index &lt; 0 || index &gt; size()
*/
public void add(int index, int value) {
if (index < 0 || index > mSize) {
throw new IndexOutOfBoundsException();
}
ensureCapacity(1);
int rightSegment = mSize - index;
mSize++;
checkBounds(index);
if (mSize - index != 0) {
System.arraycopy(mValues, index, mValues, index + 1, mSize - index);
if (rightSegment != 0) {
// Move by 1 all values from the right of 'index'
System.arraycopy(mValues, index, mValues, index + 1, rightSegment);
}
mValues[index] = value;
mSize++;
}
/**
@@ -141,12 +175,18 @@ public class IntArray implements Cloneable {
* Returns the value at the specified position in this array.
*/
public int get(int index) {
if (index >= mSize) {
throw new ArrayIndexOutOfBoundsException(mSize, index);
}
checkBounds(index);
return mValues[index];
}
/**
* Sets the value at the specified position in this array.
*/
public void set(int index, int value) {
checkBounds(index);
mValues[index] = value;
}
/**
* Returns the index of the first occurrence of the specified value in this
* array, or -1 if this array does not contain the value.
@@ -165,9 +205,7 @@ public class IntArray implements Cloneable {
* Removes the value at the specified index from this array.
*/
public void remove(int index) {
if (index >= mSize) {
throw new ArrayIndexOutOfBoundsException(mSize, index);
}
checkBounds(index);
System.arraycopy(mValues, index + 1, mValues, index, mSize - index - 1);
mSize--;
}
@@ -185,4 +223,10 @@ public class IntArray implements Cloneable {
public int[] toArray() {
return Arrays.copyOf(mValues, mSize);
}
private void checkBounds(int index) {
if (index < 0 || mSize <= index) {
throw new ArrayIndexOutOfBoundsException(mSize, index);
}
}
}

View File

@@ -17,6 +17,8 @@
package android.util;
import com.android.internal.util.ArrayUtils;
import com.android.internal.util.Preconditions;
import java.util.Arrays;
import libcore.util.EmptyArray;
/**
@@ -30,6 +32,11 @@ public class LongArray implements Cloneable {
private long[] mValues;
private int mSize;
private LongArray(long[] array, int size) {
mValues = array;
mSize = Preconditions.checkArgumentInRange(size, 0, array.length, "size");
}
/**
* Creates an empty LongArray with the default initial capacity.
*/
@@ -49,6 +56,35 @@ public class LongArray implements Cloneable {
mSize = 0;
}
/**
* Creates an LongArray wrapping the given primitive long array.
*/
public static LongArray wrap(long[] array) {
return new LongArray(array, array.length);
}
/**
* Creates an LongArray from the given primitive long array, copying it.
*/
public static LongArray fromArray(long[] array, int size) {
return wrap(Arrays.copyOf(array, size));
}
/**
* Changes the size of this LongArray. If this LongArray is shrinked, the backing array capacity
* is unchanged. If the new size is larger than backing array capacity, a new backing array is
* created from the current content of this LongArray padded with 0s.
*/
public void resize(int newSize) {
Preconditions.checkArgumentNonnegative(newSize);
if (newSize <= mValues.length) {
Arrays.fill(mValues, newSize, mValues.length, 0);
} else {
ensureCapacity(newSize - mSize);
}
mSize = newSize;
}
/**
* Appends the specified value to the end of this array.
*/
@@ -57,23 +93,23 @@ public class LongArray implements Cloneable {
}
/**
* Inserts a value at the specified position in this array.
* Inserts a value at the specified position in this array. If the specified index is equal to
* the length of the array, the value is added at the end.
*
* @throws IndexOutOfBoundsException when index &lt; 0 || index &gt; size()
*/
public void add(int index, long value) {
if (index < 0 || index > mSize) {
throw new IndexOutOfBoundsException();
}
ensureCapacity(1);
int rightSegment = mSize - index;
mSize++;
checkBounds(index);
if (mSize - index != 0) {
System.arraycopy(mValues, index, mValues, index + 1, mSize - index);
if (rightSegment != 0) {
// Move by 1 all values from the right of 'index'
System.arraycopy(mValues, index, mValues, index + 1, rightSegment);
}
mValues[index] = value;
mSize++;
}
/**
@@ -126,12 +162,18 @@ public class LongArray implements Cloneable {
* Returns the value at the specified position in this array.
*/
public long get(int index) {
if (index >= mSize) {
throw new ArrayIndexOutOfBoundsException(mSize, index);
}
checkBounds(index);
return mValues[index];
}
/**
* Sets the value at the specified position in this array.
*/
public void set(int index, long value) {
checkBounds(index);
mValues[index] = value;
}
/**
* Returns the index of the first occurrence of the specified value in this
* array, or -1 if this array does not contain the value.
@@ -150,9 +192,7 @@ public class LongArray implements Cloneable {
* Removes the value at the specified index from this array.
*/
public void remove(int index) {
if (index >= mSize) {
throw new ArrayIndexOutOfBoundsException(mSize, index);
}
checkBounds(index);
System.arraycopy(mValues, index + 1, mValues, index, mSize - index - 1);
mSize--;
}
@@ -163,4 +203,17 @@ public class LongArray implements Cloneable {
public int size() {
return mSize;
}
/**
* Returns a new array with the contents of this LongArray.
*/
public long[] toArray() {
return Arrays.copyOf(mValues, mSize);
}
private void checkBounds(int index) {
if (index < 0 || mSize <= index) {
throw new ArrayIndexOutOfBoundsException(mSize, index);
}
}
}

View File

@@ -0,0 +1,84 @@
/*
* Copyright (C) 2017 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package android.util;
import static org.junit.Assert.assertArrayEquals;
import static org.junit.Assert.assertEquals;
import android.support.test.filters.SmallTest;
import android.support.test.runner.AndroidJUnit4;
import org.junit.Test;
import org.junit.runner.RunWith;
@RunWith(AndroidJUnit4.class)
@SmallTest
public class IntArrayTest {
@Test
public void testIntArray() {
IntArray a = new IntArray();
a.add(1);
a.add(2);
a.add(3);
verify(new int[]{1, 2, 3}, a);
IntArray b = IntArray.fromArray(new int[]{4, 5, 6, 7, 8}, 3);
a.addAll(b);
verify(new int[]{1, 2, 3, 4, 5, 6}, a);
a.resize(2);
verify(new int[]{1, 2}, a);
a.resize(8);
verify(new int[]{1, 2, 0, 0, 0, 0, 0, 0}, a);
a.set(5, 10);
verify(new int[]{1, 2, 0, 0, 0, 10, 0, 0}, a);
a.add(5, 20);
assertEquals(20, a.get(5));
assertEquals(5, a.indexOf(20));
verify(new int[]{1, 2, 0, 0, 0, 20, 10, 0, 0}, a);
assertEquals(-1, a.indexOf(99));
a.resize(15);
a.set(14, 30);
verify(new int[]{1, 2, 0, 0, 0, 20, 10, 0, 0, 0, 0, 0, 0, 0, 30}, a);
int[] backingArray = new int[]{1, 2, 3, 4};
a = IntArray.wrap(backingArray);
a.set(0, 10);
assertEquals(10, backingArray[0]);
backingArray[1] = 20;
backingArray[2] = 30;
verify(backingArray, a);
assertEquals(2, a.indexOf(30));
a.resize(2);
assertEquals(0, backingArray[2]);
assertEquals(0, backingArray[3]);
a.add(50);
verify(new int[]{10, 20, 50}, a);
}
public void verify(int[] expected, IntArray intArray) {
assertEquals(expected.length, intArray.size());
assertArrayEquals(expected, intArray.toArray());
}
}

View File

@@ -0,0 +1,84 @@
/*
* Copyright (C) 2017 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package android.util;
import static org.junit.Assert.assertArrayEquals;
import static org.junit.Assert.assertEquals;
import android.support.test.filters.SmallTest;
import android.support.test.runner.AndroidJUnit4;
import org.junit.Test;
import org.junit.runner.RunWith;
@RunWith(AndroidJUnit4.class)
@SmallTest
public class LongArrayTest {
@Test
public void testLongArray() {
LongArray a = new LongArray();
a.add(1);
a.add(2);
a.add(3);
verify(new long[]{1, 2, 3}, a);
LongArray b = LongArray.fromArray(new long[]{4, 5, 6, 7, 8}, 3);
a.addAll(b);
verify(new long[]{1, 2, 3, 4, 5, 6}, a);
a.resize(2);
verify(new long[]{1, 2}, a);
a.resize(8);
verify(new long[]{1, 2, 0, 0, 0, 0, 0, 0}, a);
a.set(5, 10);
verify(new long[]{1, 2, 0, 0, 0, 10, 0, 0}, a);
a.add(5, 20);
assertEquals(20, a.get(5));
assertEquals(5, a.indexOf(20));
verify(new long[]{1, 2, 0, 0, 0, 20, 10, 0, 0}, a);
assertEquals(-1, a.indexOf(99));
a.resize(15);
a.set(14, 30);
verify(new long[]{1, 2, 0, 0, 0, 20, 10, 0, 0, 0, 0, 0, 0, 0, 30}, a);
long[] backingArray = new long[]{1, 2, 3, 4};
a = LongArray.wrap(backingArray);
a.set(0, 10);
assertEquals(10, backingArray[0]);
backingArray[1] = 20;
backingArray[2] = 30;
verify(backingArray, a);
assertEquals(2, a.indexOf(30));
a.resize(2);
assertEquals(0, backingArray[2]);
assertEquals(0, backingArray[3]);
a.add(50);
verify(new long[]{10, 20, 50}, a);
}
public void verify(long[] expected, LongArray longArrays) {
assertEquals(expected.length, longArrays.size());
assertArrayEquals(expected, longArrays.toArray());
}
}