Commit | Line | Data |
---|---|---|
79e08fd0 BH |
1 | /******************************************************************************* |
2 | * Copyright (c) 2011 Ericsson | |
3 | * | |
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 | |
8 | * | |
9 | * Contributors: | |
10 | * Francois Godin (copelnug@gmail.com) - Initial design and implementation | |
11 | * Mathieu Denis (mathieu.denis@polymtl.ca) - Correction and refactoring | |
12 | *******************************************************************************/ | |
13 | ||
14 | package org.eclipse.linuxtools.tmf.util; | |
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 | /** | |
23 | * <h4>Allow to create a List object that contain an already existing array.</h4> | |
24 | * <p>Works like {@link java.util.Arrays#asList} but offers more functions : | |
25 | * <ul> | |
26 | * <li>{@link #hashCode()}</li> | |
27 | * <li>{@link #equals(Object)}</li> | |
28 | * </ul></p> | |
29 | * <p>Those functions allow to use the FixedArray as the key of a {@link java.util.HashMap}.</p> | |
30 | * | |
31 | * @param <T> Type of the array content. | |
32 | */ | |
33 | public final class TmfFixedArray<T> extends AbstractList<T> implements RandomAccess { | |
34 | /** | |
35 | * Replace {@link java.util.Arrays#copyOf(Object[], int)} that do not exist in java 5. | |
36 | * @param <E> Content of the array. | |
37 | * @param array Original array to copy from. | |
38 | * @param newLength Length of the copy to be returned. | |
39 | * @return A new array consisting of the elements specified. | |
40 | */ | |
41 | @SuppressWarnings("unchecked") | |
42 | private static <E> E[] copyOf(final E[] array, int newLength) { | |
43 | E[] result = (E[])Array.newInstance(array.getClass().getComponentType(), newLength); // Is it useful to use newInstance? | |
44 | System.arraycopy(array, 0, result, 0, Math.min(array.length, newLength)); | |
45 | return result; | |
46 | } | |
47 | /** | |
48 | * Replace {@link java.util.Arrays#copyOf(Object[], int, Class)} that do not exist in java 5. | |
49 | * @param <E> Content of the array. | |
50 | * @param array Original array to copy from. | |
51 | * @param newLength Length of the copy to be returned. | |
52 | * @param newType Type of the array to be returned. | |
53 | * @return A new array consisting of the elements specified. | |
54 | */ | |
55 | @SuppressWarnings("unchecked") | |
56 | private static <E, U> E[] copyOf(final U[] array, int newLength, Class<? extends E[]> newType) { | |
57 | E[] result = (E[])Array.newInstance(newType.getComponentType(), newLength); | |
58 | System.arraycopy(array, 0, result, 0, Math.min(array.length, newLength)); | |
59 | return result; | |
60 | } | |
61 | /** | |
62 | * Replace {@link java.util.Arrays#copyOfRange(Object[], int, int)} that do not exist in java 5. | |
63 | * @param <E> Content of the array. | |
64 | * @param array Original array to copy from. | |
65 | * @param start Starting position of the range, inclusive. | |
66 | * @param end Ending position of the range, exclusive. | |
67 | * @return A new array consisting of the elements specified. The length of the new array is equal to end-start | |
68 | */ | |
69 | @SuppressWarnings("unchecked") | |
70 | private static <E> E[] copyOfRange(final E[] array, int start, int end) { | |
71 | E[] result = (E[])Array.newInstance(array.getClass().getComponentType(), end - start); | |
72 | System.arraycopy(array, start, result, 0, end - start); | |
73 | return result; | |
74 | } | |
75 | /** | |
76 | * The array. | |
77 | */ | |
78 | private final T[] fArray; | |
79 | /** | |
80 | * Constructor. | |
81 | * @param array Array to use. WILL NOT BE COPIED. | |
82 | */ | |
83 | public TmfFixedArray(final T... array) { | |
84 | fArray = array; | |
85 | } | |
86 | /** | |
87 | * Append a FixedArray to this FixedArray. | |
88 | * @param value The FixedArray to append. | |
89 | * @return A new FixedArray with the elements of the two FixedArray. | |
90 | */ | |
91 | public TmfFixedArray<T> append(final TmfFixedArray<T> value) { | |
92 | TmfFixedArray<T> result = new TmfFixedArray<T>(copyOf(fArray, fArray.length + value.size())); | |
93 | System.arraycopy(value.fArray, 0, result.fArray, fArray.length, value.fArray.length); | |
94 | return result; | |
95 | } | |
96 | /** | |
97 | * Append in order many FixedArray to this FixedArray. | |
98 | * @param values The FixedArrays to append. | |
99 | * @return A new FixedArray with the element of all the FixedArray. | |
100 | */ | |
101 | public TmfFixedArray<T> append(final TmfFixedArray<T>... values) { | |
102 | int newLength = 0; | |
103 | for(TmfFixedArray<T> value : values) | |
104 | newLength += value.size(); | |
105 | TmfFixedArray<T> result = new TmfFixedArray<T>(copyOf(fArray, fArray.length + newLength)); | |
106 | newLength = fArray.length; | |
107 | for(TmfFixedArray<T> value : values) | |
108 | { | |
109 | System.arraycopy(value.fArray, 0, result.fArray, newLength, value.fArray.length); | |
110 | newLength += value.fArray.length; | |
111 | } | |
112 | return result; | |
113 | } | |
114 | /** | |
115 | * Append an element to the array. | |
116 | * @param value Element to append. | |
117 | * @return A new FixedArray with the element appended. | |
118 | */ | |
119 | public TmfFixedArray<T> append(final T value) { | |
120 | TmfFixedArray<T> result = new TmfFixedArray<T>(copyOf(fArray, fArray.length + 1)); | |
121 | result.set(fArray.length, value); | |
122 | return result; | |
123 | } | |
124 | /** | |
125 | * Append an array of element to the array. | |
126 | * @param values Elements array to append. | |
127 | * @return A new FixedArray with the elements appended. | |
128 | */ | |
129 | public TmfFixedArray<T> append(final T... values) { | |
130 | TmfFixedArray<T> result = new TmfFixedArray<T>(copyOf(fArray, fArray.length + values.length)); | |
131 | for(int i = 0; i < values.length; ++i) | |
132 | result.set(fArray.length + i, values[i]); | |
133 | return result; | |
134 | } | |
135 | /* | |
136 | * (non-Javadoc) | |
137 | * @see java.lang.Object#clone() | |
138 | */ | |
139 | @Override | |
140 | public Object clone() | |
141 | { | |
142 | return new TmfFixedArray<T>(copyOf(fArray, fArray.length)); | |
143 | } | |
144 | /* | |
145 | * (non-Javadoc) | |
146 | * @see java.util.AbstractList#equals(java.lang.Object) | |
147 | */ | |
148 | @Override | |
149 | public boolean equals(Object o) { | |
150 | if(o instanceof TmfFixedArray<?>) | |
151 | return Arrays.equals(fArray, ((TmfFixedArray<?>)o).fArray); | |
152 | if(!(o instanceof List)) | |
153 | return false; | |
154 | for(int i = 0; i < fArray.length; ++i) | |
155 | if(!fArray[i].equals((List<?>)o)) | |
156 | return false; | |
157 | return true; | |
158 | } | |
159 | /* | |
160 | * (non-Javadoc) | |
161 | * @see java.util.AbstractList#get(int) | |
162 | */ | |
163 | @Override | |
164 | public T get(int index) { | |
165 | return fArray[index]; | |
166 | } | |
167 | /** | |
168 | * Get the array reference. | |
169 | * @return The array reference. | |
170 | * @see #toArray FixedArray.toArray() to get a copy of the array. | |
171 | */ | |
172 | public T[] getArray() { | |
173 | return fArray; | |
174 | } | |
175 | /* | |
176 | * (non-Javadoc) | |
177 | * @see java.util.AbstractList#hashCode() | |
178 | */ | |
179 | @Override | |
180 | public int hashCode() { | |
181 | return Arrays.hashCode(fArray); | |
182 | } | |
183 | /* | |
184 | * (non-Javadoc) | |
185 | * @see java.util.AbstractList#set(int, java.lang.Object) | |
186 | */ | |
187 | @Override | |
188 | public T set(int index, T element) { | |
189 | T temp = fArray[index]; | |
190 | fArray[index] = element; | |
191 | return temp; | |
192 | } | |
193 | /* | |
194 | * (non-Javadoc) | |
195 | * @see java.util.AbstractCollection#size() | |
196 | */ | |
197 | @Override | |
198 | public int size() { | |
199 | return fArray.length; | |
200 | } | |
201 | /** | |
202 | * Get a array covering only a part of the array. | |
203 | * @param start Starting position of the new array. | |
204 | * @return A new array covering the elements specified. | |
205 | */ | |
206 | public TmfFixedArray<T> subArray(int start) { | |
207 | return new TmfFixedArray<T>(copyOfRange(fArray, start, fArray.length)); | |
208 | } | |
209 | /** | |
210 | * Get a array covering only a part of the array. | |
211 | * @param start Starting position of the new array. | |
212 | * @param length Number of element to include in the new array. | |
213 | * @return A new array covering the elements specified. | |
214 | */ | |
215 | public TmfFixedArray<T> subArray(int start, int length) { | |
216 | return new TmfFixedArray<T>(copyOfRange(fArray, start, length + start)); | |
217 | } | |
218 | /* | |
219 | * (non-Javadoc) | |
220 | * @see java.util.AbstractCollection#toArray() | |
221 | */ | |
222 | @Override | |
223 | public T[] toArray() | |
224 | { | |
225 | return copyOf(fArray, fArray.length); | |
226 | } | |
227 | /* | |
228 | * (non-Javadoc) | |
229 | * @see java.util.AbstractCollection#toArray(T[]) | |
230 | */ | |
231 | @Override | |
232 | @SuppressWarnings("unchecked") | |
233 | public <E> E[] toArray(E[] array) | |
234 | { | |
235 | if(array.length < fArray.length) | |
236 | return copyOf(fArray, fArray.length,(Class<? extends E[]>)array.getClass()); | |
237 | System.arraycopy(fArray, 0, array, 0, fArray.length); | |
238 | if(array.length > fArray.length) | |
239 | array[fArray.length] = null; | |
240 | return array; | |
241 | } | |
242 | /* | |
243 | * (non-Javadoc) | |
244 | * @see java.util.AbstractCollection#toString() | |
245 | */ | |
246 | @Override | |
247 | public String toString() { | |
248 | return Arrays.toString(fArray); | |
249 | } | |
250 | } |