Commit | Line | Data |
---|---|---|
79e08fd0 | 1 | /******************************************************************************* |
2f2265e2 | 2 | * Copyright (c) 2011, 2012 Ericsson |
9b749023 | 3 | * |
79e08fd0 BH |
4 | * All rights reserved. This program and the accompanying materials are |
5 | * made available under the terms of the Eclipse Public License v1.0 which | |
6 | * accompanies this distribution, and is available at | |
7 | * http://www.eclipse.org/legal/epl-v10.html | |
9b749023 | 8 | * |
79e08fd0 | 9 | * Contributors: |
09667aa4 MD |
10 | * Francois Godin <copelnug@gmail.com> - Initial design and implementation |
11 | * Mathieu Denis <mathieu.denis@polymtl.ca> - Correction and refactoring | |
79e08fd0 BH |
12 | *******************************************************************************/ |
13 | ||
6c13869b | 14 | package org.eclipse.linuxtools.tmf.core.util; |
79e08fd0 BH |
15 | |
16 | import java.lang.reflect.Array; | |
17 | import java.util.AbstractList; | |
18 | import java.util.Arrays; | |
19 | import java.util.List; | |
20 | import java.util.RandomAccess; | |
21 | ||
22 | /** | |
09667aa4 MD |
23 | * Allow to create a List object that contain an already existing array. Works |
24 | * like {@link java.util.Arrays#asList} but contains more functions : | |
79e08fd0 | 25 | * <ul> |
09667aa4 MD |
26 | * <li>{@link #hashCode()}</li> |
27 | * <li>{@link #equals(Object)}</li> | |
28 | * </ul> | |
29 | * Those functions allow to use the FixedArray as the key of a | |
30 | * {@link java.util.HashMap}. | |
79e08fd0 | 31 | * |
2f2265e2 BH |
32 | * @version 1.0 |
33 | * @author Francois Godin | |
34 | * | |
09667aa4 MD |
35 | * @param <T> |
36 | * Type of the array content. | |
79e08fd0 | 37 | */ |
6e85c58d | 38 | public final class TmfFixedArray<T> extends AbstractList<T> implements RandomAccess, Cloneable { |
79e08fd0 | 39 | /** |
09667aa4 MD |
40 | * Replace {@link java.util.Arrays#copyOf(Object[], int)} that do not exist |
41 | * in java 5. | |
42 | * | |
43 | * @param <E> | |
44 | * Content of the array. | |
45 | * @param array | |
46 | * Original array to copy from. | |
47 | * @param newLength | |
48 | * Length of the copy to be returned. | |
79e08fd0 BH |
49 | * @return A new array consisting of the elements specified. |
50 | */ | |
79e08fd0 | 51 | private static <E> E[] copyOf(final E[] array, int newLength) { |
09667aa4 MD |
52 | // FIXME Is it useful to use newInstance? |
53 | E[] result = (E[]) Array.newInstance(array.getClass().getComponentType(), newLength); | |
79e08fd0 BH |
54 | System.arraycopy(array, 0, result, 0, Math.min(array.length, newLength)); |
55 | return result; | |
56 | } | |
09667aa4 | 57 | |
79e08fd0 | 58 | /** |
09667aa4 MD |
59 | * Replace {@link java.util.Arrays#copyOf(Object[], int, Class)} that do not |
60 | * exist in java 5. | |
61 | * | |
62 | * @param <E> | |
63 | * Content of the array. | |
64 | * @param array | |
65 | * Original array to copy from. | |
66 | * @param newLength | |
67 | * Length of the copy to be returned. | |
68 | * @param newType | |
69 | * Type of the array to be returned. | |
79e08fd0 BH |
70 | * @return A new array consisting of the elements specified. |
71 | */ | |
79e08fd0 BH |
72 | private static <E, U> E[] copyOf(final U[] array, int newLength, Class<? extends E[]> newType) { |
73 | E[] result = (E[])Array.newInstance(newType.getComponentType(), newLength); | |
74 | System.arraycopy(array, 0, result, 0, Math.min(array.length, newLength)); | |
75 | return result; | |
76 | } | |
09667aa4 | 77 | |
79e08fd0 | 78 | /** |
09667aa4 MD |
79 | * Replace {@link java.util.Arrays#copyOfRange(Object[], int, int)} that do |
80 | * not exist in java 5. | |
81 | * | |
82 | * @param <E> | |
83 | * Content of the array. | |
84 | * @param array | |
85 | * Original array to copy from. | |
86 | * @param start | |
87 | * Starting position of the range, inclusive. | |
88 | * @param end | |
89 | * Ending position of the range, exclusive. | |
90 | * @return A new array consisting of the elements specified. The length of | |
91 | * the new array is equal to end-start | |
79e08fd0 | 92 | */ |
79e08fd0 BH |
93 | private static <E> E[] copyOfRange(final E[] array, int start, int end) { |
94 | E[] result = (E[])Array.newInstance(array.getClass().getComponentType(), end - start); | |
95 | System.arraycopy(array, start, result, 0, end - start); | |
96 | return result; | |
97 | } | |
09667aa4 | 98 | |
79e08fd0 BH |
99 | /** |
100 | * The array. | |
101 | */ | |
102 | private final T[] fArray; | |
09667aa4 | 103 | |
79e08fd0 BH |
104 | /** |
105 | * Constructor. | |
09667aa4 MD |
106 | * |
107 | * @param array | |
108 | * Array to use. WILL NOT BE COPIED. | |
79e08fd0 BH |
109 | */ |
110 | public TmfFixedArray(final T... array) { | |
9b749023 | 111 | fArray = array; |
79e08fd0 | 112 | } |
09667aa4 | 113 | |
79e08fd0 BH |
114 | /** |
115 | * Append a FixedArray to this FixedArray. | |
09667aa4 MD |
116 | * |
117 | * @param value | |
118 | * The FixedArray to append. | |
79e08fd0 BH |
119 | * @return A new FixedArray with the elements of the two FixedArray. |
120 | */ | |
121 | public TmfFixedArray<T> append(final TmfFixedArray<T> value) { | |
122 | TmfFixedArray<T> result = new TmfFixedArray<T>(copyOf(fArray, fArray.length + value.size())); | |
123 | System.arraycopy(value.fArray, 0, result.fArray, fArray.length, value.fArray.length); | |
124 | return result; | |
125 | } | |
09667aa4 | 126 | |
79e08fd0 BH |
127 | /** |
128 | * Append in order many FixedArray to this FixedArray. | |
09667aa4 MD |
129 | * |
130 | * @param values | |
131 | * The FixedArrays to append. | |
79e08fd0 BH |
132 | * @return A new FixedArray with the element of all the FixedArray. |
133 | */ | |
134 | public TmfFixedArray<T> append(final TmfFixedArray<T>... values) { | |
135 | int newLength = 0; | |
09667aa4 | 136 | for (TmfFixedArray<T> value : values) { |
79e08fd0 | 137 | newLength += value.size(); |
9b749023 | 138 | } |
79e08fd0 BH |
139 | TmfFixedArray<T> result = new TmfFixedArray<T>(copyOf(fArray, fArray.length + newLength)); |
140 | newLength = fArray.length; | |
09667aa4 | 141 | for (TmfFixedArray<T> value : values) { |
79e08fd0 BH |
142 | System.arraycopy(value.fArray, 0, result.fArray, newLength, value.fArray.length); |
143 | newLength += value.fArray.length; | |
144 | } | |
145 | return result; | |
146 | } | |
09667aa4 | 147 | |
79e08fd0 BH |
148 | /** |
149 | * Append an element to the array. | |
09667aa4 MD |
150 | * |
151 | * @param value | |
152 | * Element to append. | |
79e08fd0 BH |
153 | * @return A new FixedArray with the element appended. |
154 | */ | |
155 | public TmfFixedArray<T> append(final T value) { | |
156 | TmfFixedArray<T> result = new TmfFixedArray<T>(copyOf(fArray, fArray.length + 1)); | |
157 | result.set(fArray.length, value); | |
158 | return result; | |
159 | } | |
09667aa4 | 160 | |
79e08fd0 BH |
161 | /** |
162 | * Append an array of element to the array. | |
09667aa4 MD |
163 | * |
164 | * @param values | |
165 | * Elements array to append. | |
79e08fd0 BH |
166 | * @return A new FixedArray with the elements appended. |
167 | */ | |
168 | public TmfFixedArray<T> append(final T... values) { | |
169 | TmfFixedArray<T> result = new TmfFixedArray<T>(copyOf(fArray, fArray.length + values.length)); | |
09667aa4 | 170 | for (int i = 0; i < values.length; ++i) { |
79e08fd0 | 171 | result.set(fArray.length + i, values[i]); |
9b749023 | 172 | } |
79e08fd0 BH |
173 | return result; |
174 | } | |
09667aa4 | 175 | |
79e08fd0 BH |
176 | /* |
177 | * (non-Javadoc) | |
09667aa4 | 178 | * |
79e08fd0 BH |
179 | * @see java.lang.Object#clone() |
180 | */ | |
181 | @Override | |
09667aa4 | 182 | public Object clone() { |
79e08fd0 BH |
183 | return new TmfFixedArray<T>(copyOf(fArray, fArray.length)); |
184 | } | |
09667aa4 | 185 | |
79e08fd0 BH |
186 | /* |
187 | * (non-Javadoc) | |
09667aa4 | 188 | * |
79e08fd0 BH |
189 | * @see java.util.AbstractList#equals(java.lang.Object) |
190 | */ | |
191 | @Override | |
192 | public boolean equals(Object o) { | |
09667aa4 MD |
193 | if (o instanceof TmfFixedArray<?>) { |
194 | return Arrays.equals(fArray, ((TmfFixedArray<?>) o).fArray); | |
9b749023 | 195 | } |
09667aa4 | 196 | if (!(o instanceof List)) { |
79e08fd0 | 197 | return false; |
9b749023 | 198 | } |
09667aa4 MD |
199 | for (int i = 0; i < fArray.length; ++i) { |
200 | if (!fArray[i].equals(o)) { | |
79e08fd0 | 201 | return false; |
9b749023 AM |
202 | } |
203 | } | |
79e08fd0 BH |
204 | return true; |
205 | } | |
09667aa4 | 206 | |
79e08fd0 BH |
207 | /* |
208 | * (non-Javadoc) | |
09667aa4 | 209 | * |
79e08fd0 BH |
210 | * @see java.util.AbstractList#get(int) |
211 | */ | |
212 | @Override | |
213 | public T get(int index) { | |
214 | return fArray[index]; | |
215 | } | |
09667aa4 | 216 | |
79e08fd0 BH |
217 | /** |
218 | * Get the array reference. | |
09667aa4 | 219 | * |
79e08fd0 BH |
220 | * @return The array reference. |
221 | * @see #toArray FixedArray.toArray() to get a copy of the array. | |
222 | */ | |
223 | public T[] getArray() { | |
224 | return fArray; | |
225 | } | |
09667aa4 | 226 | |
79e08fd0 BH |
227 | /* |
228 | * (non-Javadoc) | |
09667aa4 | 229 | * |
79e08fd0 BH |
230 | * @see java.util.AbstractList#hashCode() |
231 | */ | |
232 | @Override | |
233 | public int hashCode() { | |
234 | return Arrays.hashCode(fArray); | |
235 | } | |
09667aa4 | 236 | |
79e08fd0 BH |
237 | /* |
238 | * (non-Javadoc) | |
09667aa4 | 239 | * |
79e08fd0 BH |
240 | * @see java.util.AbstractList#set(int, java.lang.Object) |
241 | */ | |
242 | @Override | |
243 | public T set(int index, T element) { | |
244 | T temp = fArray[index]; | |
245 | fArray[index] = element; | |
246 | return temp; | |
247 | } | |
09667aa4 | 248 | |
79e08fd0 BH |
249 | /* |
250 | * (non-Javadoc) | |
09667aa4 | 251 | * |
79e08fd0 BH |
252 | * @see java.util.AbstractCollection#size() |
253 | */ | |
254 | @Override | |
255 | public int size() { | |
256 | return fArray.length; | |
257 | } | |
09667aa4 | 258 | |
79e08fd0 BH |
259 | /** |
260 | * Get a array covering only a part of the array. | |
09667aa4 MD |
261 | * |
262 | * @param start | |
263 | * Starting position of the new array. | |
79e08fd0 BH |
264 | * @return A new array covering the elements specified. |
265 | */ | |
266 | public TmfFixedArray<T> subArray(int start) { | |
267 | return new TmfFixedArray<T>(copyOfRange(fArray, start, fArray.length)); | |
268 | } | |
09667aa4 | 269 | |
79e08fd0 BH |
270 | /** |
271 | * Get a array covering only a part of the array. | |
09667aa4 MD |
272 | * |
273 | * @param start | |
274 | * Starting position of the new array. | |
275 | * @param length | |
276 | * Number of element to include in the new array. | |
79e08fd0 BH |
277 | * @return A new array covering the elements specified. |
278 | */ | |
279 | public TmfFixedArray<T> subArray(int start, int length) { | |
280 | return new TmfFixedArray<T>(copyOfRange(fArray, start, length + start)); | |
281 | } | |
09667aa4 | 282 | |
79e08fd0 BH |
283 | /* |
284 | * (non-Javadoc) | |
09667aa4 | 285 | * |
79e08fd0 BH |
286 | * @see java.util.AbstractCollection#toArray() |
287 | */ | |
288 | @Override | |
09667aa4 | 289 | public T[] toArray() { |
79e08fd0 BH |
290 | return copyOf(fArray, fArray.length); |
291 | } | |
09667aa4 | 292 | |
79e08fd0 BH |
293 | /* |
294 | * (non-Javadoc) | |
09667aa4 | 295 | * |
79e08fd0 BH |
296 | * @see java.util.AbstractCollection#toArray(T[]) |
297 | */ | |
298 | @Override | |
09667aa4 MD |
299 | public <E> E[] toArray(E[] array) { |
300 | if (array.length < fArray.length) { | |
301 | return copyOf(fArray, fArray.length, (Class<? extends E[]>) array.getClass()); | |
9b749023 | 302 | } |
79e08fd0 | 303 | System.arraycopy(fArray, 0, array, 0, fArray.length); |
09667aa4 | 304 | if (array.length > fArray.length) { |
79e08fd0 | 305 | array[fArray.length] = null; |
9b749023 | 306 | } |
79e08fd0 BH |
307 | return array; |
308 | } | |
09667aa4 | 309 | |
79e08fd0 BH |
310 | /* |
311 | * (non-Javadoc) | |
09667aa4 | 312 | * |
79e08fd0 BH |
313 | * @see java.util.AbstractCollection#toString() |
314 | */ | |
315 | @Override | |
316 | public String toString() { | |
317 | return Arrays.toString(fArray); | |
318 | } | |
319 | } |