• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2018 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 com.android.launcher3.util;
18 
19 import java.util.Arrays;
20 
21 /**
22  * Copy of the platform hidden implementation of android.util.IntArray.
23  * Implements a growing array of int primitives.
24  */
25 public class IntArray implements Cloneable {
26     private static final int MIN_CAPACITY_INCREMENT = 12;
27 
28     private static final int[] EMPTY_INT = new int[0];
29 
30     /* package private */ int[] mValues;
31     /* package private */ int mSize;
32 
IntArray(int[] array, int size)33     private  IntArray(int[] array, int size) {
34         mValues = array;
35         mSize = size;
36     }
37 
38     /**
39      * Creates an empty IntArray with the default initial capacity.
40      */
IntArray()41     public IntArray() {
42         this(10);
43     }
44 
45     /**
46      * Creates an empty IntArray with the specified initial capacity.
47      */
IntArray(int initialCapacity)48     public IntArray(int initialCapacity) {
49         if (initialCapacity == 0) {
50             mValues = EMPTY_INT;
51         } else {
52             mValues = new int[initialCapacity];
53         }
54         mSize = 0;
55     }
56 
57     /**
58      * Creates an IntArray wrapping the given primitive int array.
59      */
wrap(int... array)60     public static IntArray wrap(int... array) {
61         return new IntArray(array, array.length);
62     }
63 
64     /**
65      * Appends the specified value to the end of this array.
66      */
add(int value)67     public void add(int value) {
68         add(mSize, value);
69     }
70 
71     /**
72      * Inserts a value at the specified position in this array. If the specified index is equal to
73      * the length of the array, the value is added at the end.
74      *
75      * @throws IndexOutOfBoundsException when index < 0 || index > size()
76      */
add(int index, int value)77     public void add(int index, int value) {
78         ensureCapacity(1);
79         int rightSegment = mSize - index;
80         mSize++;
81         checkBounds(mSize, index);
82 
83         if (rightSegment != 0) {
84             // Move by 1 all values from the right of 'index'
85             System.arraycopy(mValues, index, mValues, index + 1, rightSegment);
86         }
87 
88         mValues[index] = value;
89     }
90 
91     /**
92      * Adds the values in the specified array to this array.
93      */
addAll(IntArray values)94     public void addAll(IntArray values) {
95         final int count = values.mSize;
96         ensureCapacity(count);
97 
98         System.arraycopy(values.mValues, 0, mValues, mSize, count);
99         mSize += count;
100     }
101 
102     /**
103      * Sets the array to be same as {@param other}
104      */
copyFrom(IntArray other)105     public void copyFrom(IntArray other) {
106         clear();
107         addAll(other);
108     }
109 
110     /**
111      * Ensures capacity to append at least <code>count</code> values.
112      */
ensureCapacity(int count)113     private void ensureCapacity(int count) {
114         final int currentSize = mSize;
115         final int minCapacity = currentSize + count;
116         if (minCapacity >= mValues.length) {
117             final int targetCap = currentSize + (currentSize < (MIN_CAPACITY_INCREMENT / 2) ?
118                     MIN_CAPACITY_INCREMENT : currentSize >> 1);
119             final int newCapacity = targetCap > minCapacity ? targetCap : minCapacity;
120             final int[] newValues = new int[newCapacity];
121             System.arraycopy(mValues, 0, newValues, 0, currentSize);
122             mValues = newValues;
123         }
124     }
125 
126     /**
127      * Removes all values from this array.
128      */
clear()129     public void clear() {
130         mSize = 0;
131     }
132 
133     @Override
clone()134     public IntArray clone() {
135         return wrap(toArray());
136     }
137 
138     @Override
equals(Object obj)139     public boolean equals(Object obj) {
140         if (obj == this) {
141             return true;
142         }
143         if (obj instanceof IntArray) {
144             IntArray arr = (IntArray) obj;
145             if (mSize == arr.mSize) {
146                 for (int i = 0; i < mSize; i++) {
147                     if (arr.mValues[i] != mValues[i]) {
148                         return false;
149                     }
150                 }
151                 return true;
152             }
153         }
154         return false;
155     }
156 
157     /**
158      * Returns the value at the specified position in this array.
159      */
get(int index)160     public int get(int index) {
161         checkBounds(mSize, index);
162         return mValues[index];
163     }
164 
165     /**
166      * Sets the value at the specified position in this array.
167      */
set(int index, int value)168     public void set(int index, int value) {
169         checkBounds(mSize, index);
170         mValues[index] = value;
171     }
172 
173     /**
174      * Returns the index of the first occurrence of the specified value in this
175      * array, or -1 if this array does not contain the value.
176      */
indexOf(int value)177     public int indexOf(int value) {
178         final int n = mSize;
179         for (int i = 0; i < n; i++) {
180             if (mValues[i] == value) {
181                 return i;
182             }
183         }
184         return -1;
185     }
186 
contains(int value)187     public boolean contains(int value) {
188         return indexOf(value) >= 0;
189     }
190 
isEmpty()191     public boolean isEmpty() {
192         return mSize == 0;
193     }
194 
195     /**
196      * Removes the value at the specified index from this array.
197      */
removeIndex(int index)198     public void removeIndex(int index) {
199         checkBounds(mSize, index);
200         System.arraycopy(mValues, index + 1, mValues, index, mSize - index - 1);
201         mSize--;
202     }
203 
204     /**
205      * Removes the values if it exists
206      */
removeValue(int value)207     public void removeValue(int value) {
208         int index = indexOf(value);
209         if (index >= 0) {
210             removeIndex(index);
211         }
212     }
213 
214     /**
215      * Removes the values if it exists
216      */
removeAllValues(IntArray values)217     public void removeAllValues(IntArray values) {
218         for (int i = 0; i < values.mSize; i++) {
219             removeValue(values.mValues[i]);
220         }
221     }
222 
223     /**
224      * Returns the number of values in this array.
225      */
size()226     public int size() {
227         return mSize;
228     }
229 
230     /**
231      * Returns a new array with the contents of this IntArray.
232      */
toArray()233     public int[] toArray() {
234         return mSize == 0 ? EMPTY_INT : Arrays.copyOf(mValues, mSize);
235     }
236 
237     /**
238      * Returns a comma separate list of all values.
239      */
toConcatString()240     public String toConcatString() {
241         StringBuilder b = new StringBuilder();
242         for (int i = 0; i < mSize ; i++) {
243             if (i > 0) {
244                 b.append(", ");
245             }
246             b.append(mValues[i]);
247         }
248         return b.toString();
249     }
250 
251     /**
252      * Throws {@link ArrayIndexOutOfBoundsException} if the index is out of bounds.
253      *
254      * @param len length of the array. Must be non-negative
255      * @param index the index to check
256      * @throws ArrayIndexOutOfBoundsException if the {@code index} is out of bounds of the array
257      */
checkBounds(int len, int index)258     private static void checkBounds(int len, int index) {
259         if (index < 0 || len <= index) {
260             throw new ArrayIndexOutOfBoundsException("length=" + len + "; index=" + index);
261         }
262     }
263 }