• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
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 
17 package android.util;
18 
19 import com.android.internal.util.ArrayUtils;
20 import com.android.internal.util.Preconditions;
21 
22 import libcore.util.EmptyArray;
23 
24 import java.util.Arrays;
25 
26 /**
27  * Implements a growing array of int primitives.
28  *
29  * @hide
30  */
31 public class IntArray implements Cloneable {
32     private static final int MIN_CAPACITY_INCREMENT = 12;
33 
34     private int[] mValues;
35     private int mSize;
36 
IntArray(int[] array, int size)37     private IntArray(int[] array, int size) {
38         mValues = array;
39         mSize = Preconditions.checkArgumentInRange(size, 0, array.length, "size");
40     }
41 
42     /**
43      * Creates an empty IntArray with the default initial capacity.
44      */
IntArray()45     public IntArray() {
46         this(10);
47     }
48 
49     /**
50      * Creates an empty IntArray with the specified initial capacity.
51      */
IntArray(int initialCapacity)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     /**
62      * Creates an IntArray wrapping the given primitive int array.
63      */
wrap(int[] array)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      */
fromArray(int[] array, int size)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      */
resize(int newSize)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     /**
91      * Appends the specified value to the end of this array.
92      */
add(int value)93     public void add(int value) {
94         add(mSize, value);
95     }
96 
97     /**
98      * 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.
100      *
101      * @throws IndexOutOfBoundsException when index &lt; 0 || index &gt; size()
102      */
add(int index, int value)103     public void add(int index, int value) {
104         ensureCapacity(1);
105         int rightSegment = mSize - index;
106         mSize++;
107         ArrayUtils.checkBounds(mSize, index);
108 
109         if (rightSegment != 0) {
110             // Move by 1 all values from the right of 'index'
111             System.arraycopy(mValues, index, mValues, index + 1, rightSegment);
112         }
113 
114         mValues[index] = value;
115     }
116 
117     /**
118      * 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      */
binarySearch(int value)131     public int binarySearch(int value) {
132         return ContainerHelpers.binarySearch(mValues, mSize, value);
133     }
134 
135     /**
136      * Adds the values in the specified array to this array.
137      */
addAll(IntArray values)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      * Adds the values in the specified array to this array.
148      */
addAll(int[] values)149     public void addAll(int[] values) {
150         final int count = values.length;
151         ensureCapacity(count);
152 
153         System.arraycopy(values, 0, mValues, mSize, count);
154         mSize += count;
155     }
156 
157     /**
158      * Ensures capacity to append at least <code>count</code> values.
159      */
ensureCapacity(int count)160     private void ensureCapacity(int count) {
161         final int currentSize = mSize;
162         final int minCapacity = currentSize + count;
163         if (minCapacity >= mValues.length) {
164             final int targetCap = currentSize + (currentSize < (MIN_CAPACITY_INCREMENT / 2) ?
165                     MIN_CAPACITY_INCREMENT : currentSize >> 1);
166             final int newCapacity = targetCap > minCapacity ? targetCap : minCapacity;
167             final int[] newValues = ArrayUtils.newUnpaddedIntArray(newCapacity);
168             System.arraycopy(mValues, 0, newValues, 0, currentSize);
169             mValues = newValues;
170         }
171     }
172 
173     /**
174      * Removes all values from this array.
175      */
clear()176     public void clear() {
177         mSize = 0;
178     }
179 
180     @Override
clone()181     public IntArray clone() {
182         return new IntArray(mValues.clone(), mSize);
183     }
184 
185     /**
186      * Returns the value at the specified position in this array.
187      */
get(int index)188     public int get(int index) {
189         ArrayUtils.checkBounds(mSize, index);
190         return mValues[index];
191     }
192 
193     /**
194      * Sets the value at the specified position in this array.
195      */
set(int index, int value)196     public void set(int index, int value) {
197         ArrayUtils.checkBounds(mSize, index);
198         mValues[index] = value;
199     }
200 
201     /**
202      * Returns the index of the first occurrence of the specified value in this
203      * array, or -1 if this array does not contain the value.
204      */
indexOf(int value)205     public int indexOf(int value) {
206         final int n = mSize;
207         for (int i = 0; i < n; i++) {
208             if (mValues[i] == value) {
209                 return i;
210             }
211         }
212         return -1;
213     }
214 
215     /**
216      * Removes the value at the specified index from this array.
217      */
remove(int index)218     public void remove(int index) {
219         ArrayUtils.checkBounds(mSize, index);
220         System.arraycopy(mValues, index + 1, mValues, index, mSize - index - 1);
221         mSize--;
222     }
223 
224     /**
225      * Returns the number of values in this array.
226      */
size()227     public int size() {
228         return mSize;
229     }
230 
231     /**
232      * Returns a new array with the contents of this IntArray.
233      */
toArray()234     public int[] toArray() {
235         return Arrays.copyOf(mValues, mSize);
236     }
237 }
238