1 /*******************************************************************************
\r
2 * Copyright (c) 2010 Association for Decentralized Information Management in
\r
4 * All rights reserved. This program and the accompanying materials
\r
5 * are made available under the terms of the Eclipse Public License v1.0
\r
6 * which accompanies this distribution, and is available at
\r
7 * http://www.eclipse.org/legal/epl-v10.html
\r
10 * VTT Technical Research Centre of Finland - initial API and implementation
\r
11 *******************************************************************************/
\r
12 package org.simantics.databoard.util;
14 import java.lang.reflect.Array;
\r
16 public class ArrayUtils {
\r
19 * Drop elements from array
\r
21 * @param src source array
\r
22 * @param elementsToDrop
\r
23 * @return src or new array
\r
26 public static <T> T[] dropElements(T src[], T...elementsToDrop)
\r
28 if (src.length==0) return src;
\r
32 for (T b : elementsToDrop)
\r
33 if (a==b) continue nextA;
\r
36 if (count==src.length) return src;
\r
38 Class<?> componentClass = src.getClass().getComponentType();
\r
39 @SuppressWarnings("unchecked")
\r
40 T[] result = (T[]) Array.newInstance(componentClass, count);
\r
41 if (count==0) return result;
\r
45 for (T b : elementsToDrop)
\r
46 if (a==b) continue nextA2;
\r
47 result[index++] = a;
\r
53 * Replace first occurance of object with another
\r
59 public static void replaceFirst(Object src[], Object from, Object to) {
\r
60 for (int i=0; i<src.length; i++)
\r
61 if (src[i] == from) {
\r
68 * Concatenate two arrays
\r
71 * @return A new array with elements of a followed by elements of b
\r
73 public static <T> T[] concatenate(T[] a, T[] b) {
\r
74 @SuppressWarnings("unchecked")
\r
75 Class<? extends T> compType = (Class<? extends T>) getCommonBase(a.getClass().getComponentType(), b.getClass().getComponentType());
\r
76 if (compType == null)
\r
77 throw new RuntimeException("Could not deduce common array type for " + a.getClass().getName() + " and " + b.getClass().getName());
\r
78 return concatenate(a, b, compType);
\r
82 * Concatenate two arrays
\r
85 * @param componentType The actual component type of the created array
\r
86 * @return A new array with elements of a followed by elements of b
\r
88 public static <T> T[] concatenate(T[] a, T[] b, Class<? extends T> componentType) {
\r
89 @SuppressWarnings("unchecked")
\r
90 T[] result = (T[]) Array.newInstance(componentType, a.length + b.length);
\r
91 System.arraycopy(a, 0, result, 0, a.length);
\r
92 System.arraycopy(b, 0, result, a.length, b.length);
\r
97 * Concatenate two arrays, cropping or extending the result to a given length
\r
100 * @param length Length of the resulting array
\r
101 * @return A new array with elements of a followed by elements of b, possibly padded with nulls to reach a given length
\r
103 public static <T> T[] concatenate(T[] a, T[] b, int length) {
\r
104 @SuppressWarnings("unchecked")
\r
105 Class<? extends T> compType = (Class<? extends T>)getCommonBase(a.getClass().getComponentType(), b.getClass().getComponentType());
\r
106 if (compType == null)
\r
107 throw new RuntimeException("Could not deduce common array type for " + a.getClass().getName() + " and " + b.getClass().getName());
\r
108 return concatenate(a, b, length, compType);
\r
112 * Concatenate two arrays, cropping or extending the result to a given length
\r
115 * @param length Length of the resulting array
\r
116 * @param componentType The actual component type of the created array
\r
117 * @return A new array with elements of a followed by elements of b, possibly padded with nulls to reach a given length
\r
119 public static <T> T[] concatenate(T[] a, T[] b, int length, Class<? extends T> componentType) {
\r
120 @SuppressWarnings("unchecked")
\r
121 T[] result = (T[]) Array.newInstance(componentType, length);
\r
122 System.arraycopy(a, 0, result, 0, Math.min(length, a.length));
\r
123 if (length > a.length)
\r
124 System.arraycopy(b, 0, result, a.length, Math.min(b.length, length - a.length));
\r
129 * Add new elements to the end of an array
\r
132 * @return A new array with elements b appended at the end
\r
135 public static <T> T[] append(T[] a, T ... b) {
\r
136 return concatenate(a, b);
\r
140 * Add new elements to the end of an array
\r
143 * @return A new array with elements b appended at the end
\r
146 public static <T> T[] append(Class<? extends T> compType, T[] a, T ... b) {
\r
147 return concatenate(a, b, compType);
\r
151 * Add new elements to the end of an array
\r
154 * @param length Length of the resulting array
\r
155 * @return A new array with elements b appended at the end
\r
158 public static <T> T[] append(int length, T[] a, T ... b) {
\r
159 return concatenate(a, b, length);
\r
163 * Add new elements to the end of an array
\r
166 * @param length Length of the resulting array
\r
167 * @return A new array with elements b appended at the end
\r
170 public static <T> T[] append(Class<? extends T> compType, int length, T[] a, T ... b) {
\r
171 return concatenate(a, b, length, compType);
\r
175 * Get an array with elements from a source array at given indices
\r
176 * @param source A source array
\r
177 * @param index An index array
\r
178 * @return A new array with element i equal to source[index[i]]
\r
180 public static <T> T[] indirection(T[] source, int[] index) {
\r
181 @SuppressWarnings("unchecked")
\r
182 T[] result = (T[]) Array.newInstance(source.getClass().getComponentType(), index.length);
\r
183 for (int i = 0; i < index.length; i++)
\r
184 result[i] = source[index[i]];
\r
189 * Get an array with given length with elements from a source array at given indices
\r
190 * @param source A source array
\r
191 * @param index An index array
\r
192 * @return A new array with element i equal to source[index[i]]. The resulting array length is set to #length.
\r
194 public static <T> T[] indirection(T[] source, int[] index, int length) {
\r
195 @SuppressWarnings("unchecked")
\r
196 T[] result = (T[]) Array.newInstance(source.getClass().getComponentType(), length);
\r
197 int n = Math.min(length, index.length);
\r
198 for (int i = 0; i < n; i++)
\r
199 result[i] = source[index[i]];
\r
204 * Get a nearest common base class for two types. An interface type is returned only if one of classes
\r
205 * is an interface type that is implemented by a superclass of the other. Thus, the returned base class for
\r
206 * String and StringBuffer is returned Object, instead of either of the possible choices of CharSequence or
\r
212 public static Class<?> getCommonBase(Class<?> a, Class<?> b) {
\r
213 if (a == null || b == null)
\r
214 return Object.class;
\r
215 else if (a.isArray() && b.isArray())
\r
216 return Array.newInstance(getCommonBase(a.getComponentType(), b.getComponentType()), 0).getClass();
\r
217 else if (a.isAssignableFrom(b))
\r
219 else if (b.isAssignableFrom(a))
\r
222 /* Due to interface definitions, these cases might return different results. */
\r
223 Class<?> ab = getCommonBase(a.getSuperclass(), b);
\r
224 Class<?> ba = getCommonBase(a, b.getSuperclass());
\r
226 /* Return the less generic one */
\r
227 return ab.isAssignableFrom(ba) ? ba : ab;
\r