1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32 package org.spf4j.base;
33
34 import com.google.common.annotations.Beta;
35 import com.google.common.annotations.GwtCompatible;
36 import com.google.common.annotations.GwtIncompatible;
37 import com.google.common.collect.ObjectArrays;
38 import java.lang.annotation.Annotation;
39 import java.lang.reflect.Array;
40
41
42
43
44
45
46 @GwtCompatible
47 public final class Arrays {
48
49 public static final Object[] EMPTY_OBJ_ARRAY = new Object[]{};
50
51 public static final Annotation[] EMPTY_ANNOT_ARRAY = new Annotation[]{};
52
53 public static final Class[] EMPTY_CLASS_ARRAY = new Class[]{};
54
55 public static final String[] EMPTY_STRING_ARRAY = new String[]{};
56
57 public static final byte[] EMPTY_BYTE_ARRAY = new byte[]{};
58
59 public static final char[] EMPTY_CHAR_ARRAY = new char[]{};
60
61 public static final boolean[] EMPTY_BOOLEAN_ARRAY = new boolean[]{};
62
63 public static final long[] EMPTY_LONG_ARRAY = new long[]{};
64
65 public static final int[] EMPTY_INT_ARRAY = new int[]{};
66
67 private static final int ARR_CPY_THR = 128;
68
69 private Arrays() {
70 }
71
72 public static double[] getColumnAsDoubles(final long[][] data, final int columnNumber) {
73 double[] result = new double[data.length];
74 for (int i = 0; i < result.length; i++) {
75 result[i] = data[i][columnNumber];
76 }
77 return result;
78 }
79
80 public static double[] getColumn(final double[][] data, final int columnNumber) {
81 double[] result = new double[data.length];
82 for (int i = 0; i < result.length; i++) {
83 result[i] = data[i][columnNumber];
84 }
85 return result;
86 }
87
88 public static double[] toDoubleArray(final long... larr) {
89 double[] result = new double[larr.length];
90 for (int i = 0; i < larr.length; i++) {
91 result[i] = larr[i];
92 }
93 return result;
94 }
95
96 public static Object[] toObjectArray(final long... larr) {
97 Object[] result = new Object[larr.length];
98 for (int i = 0; i < larr.length; i++) {
99 result[i] = larr[i];
100 }
101 return result;
102 }
103
104 public static double[] divide(final double[] arr1, final double[] arr2) {
105 double[] result = new double[arr1.length];
106 for (int i = 0; i < result.length; i++) {
107 result[i] = arr1[i] / arr2[i];
108 }
109 return result;
110 }
111
112 public static boolean deepEquals(final Object[] a1, final Object[] a2, final int starting) {
113 return deepEquals(a1, a2, starting, a1.length);
114 }
115
116 public static boolean deepEquals(final Object[] a1, final Object[] a2, final int starting, final int ending) {
117 if (a1 == a2) {
118 return true;
119 }
120 if (a1 == null || a2 == null) {
121 return false;
122 }
123 for (int i = starting; i < ending; i++) {
124 if (!java.util.Objects.deepEquals(a1[i], a2[i])) {
125 return false;
126 }
127 }
128 return true;
129 }
130
131 public static boolean equals(final byte[] a, final byte[] b, final int a1, final int b1, final int length) {
132 for (int i = a1, j = b1, k = 0; k < length; i++, j++, k++) {
133 if (a[i] != b[j]) {
134 return false;
135 }
136 }
137 return true;
138 }
139
140
141 public static int search(final char[] array, final char c) {
142 for (int i = 0; i < array.length; i++) {
143 if (array[i] == c) {
144 return i;
145 }
146 }
147 return -1;
148 }
149
150 public static <T> T[] moveOfRange(final T[] original, final int from, final int to) {
151 int newLength = to - from;
152 if (newLength < 0) {
153 throw new IllegalArgumentException(from + " > " + to);
154 }
155 T[] copy = ObjectArrays.newArray(original, newLength);
156 for (int i = from, j = 0; i < to; i++, j++) {
157 copy[j] = original[i];
158 original[i] = null;
159 }
160 return copy;
161 }
162
163 public static <T> T[] append(final T[] array, final T value) {
164 T[] result = java.util.Arrays.copyOf(array, array.length + 1);
165 result[array.length] = value;
166 return result;
167 }
168
169 @GwtIncompatible
170 public static <T> T[] preppend(final T[] array, final T value) {
171 Class<? extends Object[]> aClass = array.getClass();
172 T[] copy = ((Object) aClass == (Object) Object[].class)
173 ? (T[]) new Object[array.length + 1]
174 : (T[]) Array.newInstance(aClass.getComponentType(), array.length + 1);
175 System.arraycopy(array, 0, copy, 1, array.length);
176
177 copy[0] = value;
178 return copy;
179 }
180
181 @GwtIncompatible
182 public static <T> T[] preppend(final T[] array, final T... values) {
183 Class<? extends Object[]> aClass = array.getClass();
184 T[] copy = ((Object) aClass == (Object) Object[].class)
185 ? (T[]) new Object[array.length + values.length]
186 : (T[]) Array.newInstance(aClass.getComponentType(), array.length + values.length);
187 System.arraycopy(array, 0, copy, values.length, array.length);
188 System.arraycopy(values, 0, copy, 0, values.length);
189 return copy;
190 }
191
192 public static <T> T[] append(final T[] array, final T... values) {
193 if (values.length == 0) {
194 return array;
195 }
196 T[] result = java.util.Arrays.copyOf(array, array.length + values.length);
197 System.arraycopy(values, 0, result, array.length, values.length);
198 return result;
199 }
200
201
202 public static <T> T[] concat(final T[]... arrays) {
203 if (arrays.length < 2) {
204 throw new IllegalArgumentException("You should concatenate at least 2 arrays: "
205 + arrays.length);
206 }
207 int newLength = 0;
208 for (T[] arr : arrays) {
209 newLength += arr.length;
210 }
211 T[] result = ObjectArrays.newArray(arrays[0], newLength);
212 int destIdx = 0;
213 for (T[] arr : arrays) {
214 System.arraycopy(arr, 0, result, destIdx, arr.length);
215 destIdx += arr.length;
216 }
217 return result;
218 }
219
220 public static byte[] concat(final byte[]... arrays) {
221 if (arrays.length < 2) {
222 throw new IllegalArgumentException("You should concatenate at least 2 arrays: "
223 + arrays.length);
224 }
225 int newLength = 0;
226 for (byte[] arr : arrays) {
227 newLength += arr.length;
228 }
229 byte[] result = new byte[newLength];
230 int destIdx = 0;
231 for (byte[] arr : arrays) {
232 System.arraycopy(arr, 0, result, destIdx, arr.length);
233 destIdx += arr.length;
234 }
235 return result;
236 }
237
238 public static <T> int indexOf(final T[] array, final T content) {
239 int result = -1;
240 for (int i = 0; i < array.length; i++) {
241 if (array[i].equals(content)) {
242 return i;
243 }
244 }
245 return result;
246 }
247
248
249
250
251 @Beta
252 public static void fill(final byte[] array, final int startIdx, final int endIdx, final byte value) {
253 int len = endIdx - startIdx;
254 if (len > 0) {
255 if (endIdx > array.length || startIdx < 0) {
256 throw new IllegalArgumentException("Illegal range from " + startIdx + " to " + endIdx);
257 }
258 if (len <= ARR_CPY_THR) {
259 for (int i = startIdx; i < endIdx; i++) {
260 array[i] = value;
261 }
262 } else {
263 int fillEnd = startIdx + ARR_CPY_THR;
264 for (int i = startIdx; i < fillEnd; i++) {
265 array[i] = value;
266 }
267 array[startIdx] = value;
268 for (int i = ARR_CPY_THR; i < len; i += i) {
269 int lmi = len - i;
270 int from = startIdx + i;
271 if (lmi < i) {
272 if (lmi < ARR_CPY_THR) {
273 int xe = from + lmi;
274 for (int j = from; j < xe; j++) {
275 array[j] = value;
276 }
277 } else {
278 System.arraycopy(array, startIdx, array, from, lmi);
279 }
280 } else {
281 System.arraycopy(array, startIdx, array, from, i);
282 }
283 }
284 }
285 } else if (len < 0) {
286 throw new IllegalArgumentException("Illegal range from " + startIdx + " to " + endIdx);
287 }
288 }
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305 @Beta
306 public static <T> void fill(final T[] array, final int startIdx, final int endIdx, final T value) {
307 int len = endIdx - startIdx;
308 if (len > 0) {
309 if (endIdx > array.length || startIdx < 0) {
310 throw new IllegalArgumentException("Illegal range from " + startIdx + " to " + endIdx);
311 }
312 if (len <= ARR_CPY_THR) {
313 for (int i = startIdx; i < endIdx; i++) {
314 array[i] = value;
315 }
316 } else {
317 int fillEnd = startIdx + ARR_CPY_THR;
318 for (int i = startIdx; i < fillEnd; i++) {
319 array[i] = value;
320 }
321 array[startIdx] = value;
322 for (int i = ARR_CPY_THR; i < len; i += i) {
323 int lmi = len - i;
324 int from = startIdx + i;
325 if (lmi < i) {
326 if (lmi < ARR_CPY_THR) {
327 int xe = from + lmi;
328 for (int j = from; j < xe; j++) {
329 array[j] = value;
330 }
331 } else {
332 System.arraycopy(array, startIdx, array, from, lmi);
333 }
334 } else {
335 System.arraycopy(array, startIdx, array, from, i);
336 }
337 }
338 }
339 } else if (len < 0) {
340 throw new IllegalArgumentException("Illegal range from " + startIdx + " to " + endIdx);
341 }
342 }
343
344 @Beta
345 public static void fill(final char[] array, final int startIdx, final int endIdx, final char value) {
346 int len = endIdx - startIdx;
347 if (len > 0) {
348 if (endIdx > array.length || startIdx < 0) {
349 throw new IllegalArgumentException("Illegal range from " + startIdx + " to " + endIdx);
350 }
351 if (len <= ARR_CPY_THR) {
352 for (int i = startIdx; i < endIdx; i++) {
353 array[i] = value;
354 }
355 } else {
356 int fillEnd = startIdx + ARR_CPY_THR;
357 for (int i = startIdx; i < fillEnd; i++) {
358 array[i] = value;
359 }
360 array[startIdx] = value;
361 for (int i = ARR_CPY_THR; i < len; i += i) {
362 int lmi = len - i;
363 int from = startIdx + i;
364 if (lmi < i) {
365 if (lmi < ARR_CPY_THR) {
366 int xe = from + lmi;
367 for (int j = from; j < xe; j++) {
368 array[j] = value;
369 }
370 } else {
371 System.arraycopy(array, startIdx, array, from, lmi);
372 }
373 } else {
374 System.arraycopy(array, startIdx, array, from, i);
375 }
376 }
377 }
378 } else if (len < 0) {
379 throw new IllegalArgumentException("Illegal range from " + startIdx + " to " + endIdx);
380 }
381 }
382
383 @Beta
384 public static void fill(final int[] array, final int startIdx, final int endIdx, final int value) {
385 int len = endIdx - startIdx;
386 if (len > 0) {
387 if (endIdx > array.length || startIdx < 0) {
388 throw new IllegalArgumentException("Illegal range from " + startIdx + " to " + endIdx);
389 }
390 if (len <= ARR_CPY_THR) {
391 for (int i = startIdx; i < endIdx; i++) {
392 array[i] = value;
393 }
394 } else {
395 int fillEnd = startIdx + ARR_CPY_THR;
396 for (int i = startIdx; i < fillEnd; i++) {
397 array[i] = value;
398 }
399 array[startIdx] = value;
400 for (int i = ARR_CPY_THR; i < len; i += i) {
401 int lmi = len - i;
402 int from = startIdx + i;
403 if (lmi < i) {
404 if (lmi < ARR_CPY_THR) {
405 int xe = from + lmi;
406 for (int j = from; j < xe; j++) {
407 array[j] = value;
408 }
409 } else {
410 System.arraycopy(array, startIdx, array, from, lmi);
411 }
412 } else {
413 System.arraycopy(array, startIdx, array, from, i);
414 }
415 }
416 }
417 } else if (len < 0) {
418 throw new IllegalArgumentException("Illegal range from " + startIdx + " to " + endIdx);
419 }
420 }
421
422 @Beta
423 public static void fill(final long[] array, final int startIdx, final int endIdx, final long value) {
424 int len = endIdx - startIdx;
425 if (len > 0) {
426 if (endIdx > array.length || startIdx < 0) {
427 throw new IllegalArgumentException("Illegal range from " + startIdx + " to " + endIdx);
428 }
429 if (len <= ARR_CPY_THR) {
430 for (int i = startIdx; i < endIdx; i++) {
431 array[i] = value;
432 }
433 } else {
434 int fillEnd = startIdx + ARR_CPY_THR;
435 for (int i = startIdx; i < fillEnd; i++) {
436 array[i] = value;
437 }
438 array[startIdx] = value;
439 for (int i = ARR_CPY_THR; i < len; i += i) {
440 int lmi = len - i;
441 int from = startIdx + i;
442 if (lmi < i) {
443 if (lmi < ARR_CPY_THR) {
444 int xe = from + lmi;
445 for (int j = from; j < xe; j++) {
446 array[j] = value;
447 }
448 } else {
449 System.arraycopy(array, startIdx, array, from, lmi);
450 }
451 } else {
452 System.arraycopy(array, startIdx, array, from, i);
453 }
454 }
455 }
456 } else if (len < 0) {
457 throw new IllegalArgumentException("Illegal range from " + startIdx + " to " + endIdx);
458 }
459 }
460
461 @Beta
462 public static void fill(final double[] array, final int startIdx, final int endIdx, final double value) {
463 int len = endIdx - startIdx;
464 if (len > 0) {
465 if (endIdx > array.length || startIdx < 0) {
466 throw new IllegalArgumentException("Illegal range from " + startIdx + " to " + endIdx);
467 }
468 if (len <= ARR_CPY_THR) {
469 for (int i = startIdx; i < endIdx; i++) {
470 array[i] = value;
471 }
472 } else {
473 int fillEnd = startIdx + ARR_CPY_THR;
474 for (int i = startIdx; i < fillEnd; i++) {
475 array[i] = value;
476 }
477 array[startIdx] = value;
478 for (int i = ARR_CPY_THR; i < len; i += i) {
479 int lmi = len - i;
480 int from = startIdx + i;
481 if (lmi < i) {
482 if (lmi < ARR_CPY_THR) {
483 int xe = from + lmi;
484 for (int j = from; j < xe; j++) {
485 array[j] = value;
486 }
487 } else {
488 System.arraycopy(array, startIdx, array, from, lmi);
489 }
490 } else {
491 System.arraycopy(array, startIdx, array, from, i);
492 }
493 }
494 }
495 } else if (len < 0) {
496 throw new IllegalArgumentException("Illegal range from " + startIdx + " to " + endIdx);
497 }
498 }
499
500 public static byte[] charsToBytes(final char[] chars) {
501 byte[] bytes = new byte[chars.length * 2];
502 for (int i = 0, k = 0; i < chars.length; i++, k += 2) {
503 char v = chars[i];
504 bytes[k] = (byte) (0xff & (v >> 8));
505 bytes[k + 1] = (byte) (0xff & (v));
506 }
507 return bytes;
508 }
509
510 public static char[] bytesToChars(final byte[] bytes) {
511 char[] chars = new char[bytes.length / 2];
512 for (int i = 0, k = 0; i < chars.length; i++, k += 2) {
513 char v = (char) (((0xff & (bytes[k])) << 8) | (0xff & bytes[k + 1]));
514 chars[i] = v;
515 }
516 return chars;
517 }
518
519 }