blob: 5a74ec0e52c08a5ba99a7f0be92d1a078429dcb3 [file] [log] [blame]
Alan Viveretteffb46bf2014-10-24 12:06:11 -07001/*
2 * Copyright (C) 2014 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package android.util;
18
19import com.android.internal.util.ArrayUtils;
Hugo Benichi112962a2017-03-27 13:45:23 +090020import com.android.internal.util.Preconditions;
Neil Fuller8a1683f2018-07-03 18:46:10 +010021
Alan Viveretteffb46bf2014-10-24 12:06:11 -070022import libcore.util.EmptyArray;
23
Neil Fuller8a1683f2018-07-03 18:46:10 +010024import java.util.Arrays;
25
Alan Viveretteffb46bf2014-10-24 12:06:11 -070026/**
27 * Implements a growing array of int primitives.
28 *
29 * @hide
30 */
31public class IntArray implements Cloneable {
32 private static final int MIN_CAPACITY_INCREMENT = 12;
33
34 private int[] mValues;
35 private int mSize;
36
Hugo Benichi112962a2017-03-27 13:45:23 +090037 private IntArray(int[] array, int size) {
38 mValues = array;
39 mSize = Preconditions.checkArgumentInRange(size, 0, array.length, "size");
40 }
41
Alan Viveretteffb46bf2014-10-24 12:06:11 -070042 /**
43 * Creates an empty IntArray with the default initial capacity.
44 */
45 public IntArray() {
46 this(10);
47 }
48
49 /**
50 * Creates an empty IntArray with the specified initial capacity.
51 */
52 public IntArray(int initialCapacity) {
53 if (initialCapacity == 0) {
54 mValues = EmptyArray.INT;
55 } else {
56 mValues = ArrayUtils.newUnpaddedIntArray(initialCapacity);
57 }
58 mSize = 0;
59 }
60
61 /**
Hugo Benichi112962a2017-03-27 13:45:23 +090062 * Creates an IntArray wrapping the given primitive int array.
63 */
64 public static IntArray wrap(int[] array) {
65 return new IntArray(array, array.length);
66 }
67
68 /**
69 * Creates an IntArray from the given primitive int array, copying it.
70 */
71 public static IntArray fromArray(int[] array, int size) {
72 return wrap(Arrays.copyOf(array, size));
73 }
74
75 /**
76 * Changes the size of this IntArray. If this IntArray is shrinked, the backing array capacity
77 * is unchanged. If the new size is larger than backing array capacity, a new backing array is
78 * created from the current content of this IntArray padded with 0s.
79 */
80 public void resize(int newSize) {
81 Preconditions.checkArgumentNonnegative(newSize);
82 if (newSize <= mValues.length) {
83 Arrays.fill(mValues, newSize, mValues.length, 0);
84 } else {
85 ensureCapacity(newSize - mSize);
86 }
87 mSize = newSize;
88 }
89
90 /**
Alan Viveretteffb46bf2014-10-24 12:06:11 -070091 * Appends the specified value to the end of this array.
92 */
93 public void add(int value) {
94 add(mSize, value);
95 }
96
97 /**
Hugo Benichi112962a2017-03-27 13:45:23 +090098 * Inserts a value at the specified position in this array. If the specified index is equal to
99 * the length of the array, the value is added at the end.
Alan Viveretteffb46bf2014-10-24 12:06:11 -0700100 *
101 * @throws IndexOutOfBoundsException when index &lt; 0 || index &gt; size()
102 */
103 public void add(int index, int value) {
Alan Viveretteffb46bf2014-10-24 12:06:11 -0700104 ensureCapacity(1);
Hugo Benichi112962a2017-03-27 13:45:23 +0900105 int rightSegment = mSize - index;
106 mSize++;
Neil Fuller8a1683f2018-07-03 18:46:10 +0100107 ArrayUtils.checkBounds(mSize, index);
Alan Viveretteffb46bf2014-10-24 12:06:11 -0700108
Hugo Benichi112962a2017-03-27 13:45:23 +0900109 if (rightSegment != 0) {
110 // Move by 1 all values from the right of 'index'
111 System.arraycopy(mValues, index, mValues, index + 1, rightSegment);
Alan Viveretteffb46bf2014-10-24 12:06:11 -0700112 }
113
114 mValues[index] = value;
Alan Viveretteffb46bf2014-10-24 12:06:11 -0700115 }
116
117 /**
Zoltan Szatmary-Ban9c5dfa52015-02-23 17:20:20 +0000118 * Searches the array for the specified value using the binary search algorithm. The array must
119 * be sorted (as by the {@link Arrays#sort(int[], int, int)} method) prior to making this call.
120 * If it is not sorted, the results are undefined. If the range contains multiple elements with
121 * the specified value, there is no guarantee which one will be found.
122 *
123 * @param value The value to search for.
124 * @return index of the search key, if it is contained in the array; otherwise, <i>(-(insertion
125 * point) - 1)</i>. The insertion point is defined as the point at which the key would
126 * be inserted into the array: the index of the first element greater than the key, or
127 * {@link #size()} if all elements in the array are less than the specified key.
128 * Note that this guarantees that the return value will be >= 0 if and only if the key
129 * is found.
130 */
131 public int binarySearch(int value) {
132 return ContainerHelpers.binarySearch(mValues, mSize, value);
133 }
134
135 /**
Alan Viveretteffb46bf2014-10-24 12:06:11 -0700136 * Adds the values in the specified array to this array.
137 */
138 public void addAll(IntArray values) {
139 final int count = values.mSize;
140 ensureCapacity(count);
141
142 System.arraycopy(values.mValues, 0, mValues, mSize, count);
143 mSize += count;
144 }
145
146 /**
147 * Ensures capacity to append at least <code>count</code> values.
148 */
149 private void ensureCapacity(int count) {
150 final int currentSize = mSize;
151 final int minCapacity = currentSize + count;
152 if (minCapacity >= mValues.length) {
153 final int targetCap = currentSize + (currentSize < (MIN_CAPACITY_INCREMENT / 2) ?
154 MIN_CAPACITY_INCREMENT : currentSize >> 1);
155 final int newCapacity = targetCap > minCapacity ? targetCap : minCapacity;
156 final int[] newValues = ArrayUtils.newUnpaddedIntArray(newCapacity);
157 System.arraycopy(mValues, 0, newValues, 0, currentSize);
158 mValues = newValues;
159 }
160 }
161
162 /**
163 * Removes all values from this array.
164 */
165 public void clear() {
166 mSize = 0;
167 }
168
169 @Override
170 public IntArray clone() throws CloneNotSupportedException {
171 final IntArray clone = (IntArray) super.clone();
172 clone.mValues = mValues.clone();
173 return clone;
174 }
175
176 /**
177 * Returns the value at the specified position in this array.
178 */
179 public int get(int index) {
Neil Fuller8a1683f2018-07-03 18:46:10 +0100180 ArrayUtils.checkBounds(mSize, index);
Alan Viveretteffb46bf2014-10-24 12:06:11 -0700181 return mValues[index];
182 }
183
184 /**
Hugo Benichi112962a2017-03-27 13:45:23 +0900185 * Sets the value at the specified position in this array.
186 */
187 public void set(int index, int value) {
Neil Fuller8a1683f2018-07-03 18:46:10 +0100188 ArrayUtils.checkBounds(mSize, index);
Hugo Benichi112962a2017-03-27 13:45:23 +0900189 mValues[index] = value;
190 }
191
192 /**
Alan Viveretteffb46bf2014-10-24 12:06:11 -0700193 * Returns the index of the first occurrence of the specified value in this
194 * array, or -1 if this array does not contain the value.
195 */
196 public int indexOf(int value) {
197 final int n = mSize;
198 for (int i = 0; i < n; i++) {
199 if (mValues[i] == value) {
200 return i;
201 }
202 }
203 return -1;
204 }
205
206 /**
207 * Removes the value at the specified index from this array.
208 */
209 public void remove(int index) {
Neil Fuller8a1683f2018-07-03 18:46:10 +0100210 ArrayUtils.checkBounds(mSize, index);
Alan Viveretteffb46bf2014-10-24 12:06:11 -0700211 System.arraycopy(mValues, index + 1, mValues, index, mSize - index - 1);
212 mSize--;
213 }
214
215 /**
216 * Returns the number of values in this array.
217 */
218 public int size() {
219 return mSize;
220 }
Zoltan Szatmary-Ban9c5dfa52015-02-23 17:20:20 +0000221
222 /**
223 * Returns a new array with the contents of this IntArray.
224 */
225 public int[] toArray() {
226 return Arrays.copyOf(mValues, mSize);
227 }
Alan Viveretteffb46bf2014-10-24 12:06:11 -0700228}