001 /*
002 * Copyright (C) 2007 The Guava Authors
003 *
004 * Licensed under the Apache License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 *
008 * http://www.apache.org/licenses/LICENSE-2.0
009 *
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 * See the License for the specific language governing permissions and
014 * limitations under the License.
015 */
016
017 package com.google.common.collect;
018
019 import com.google.common.annotations.GwtCompatible;
020 import com.google.common.annotations.GwtIncompatible;
021
022 import java.util.Collection;
023
024 import javax.annotation.Nullable;
025
026 /**
027 * Static utility methods pertaining to object arrays.
028 *
029 * @author Kevin Bourrillion
030 * @since 2 (imported from Google Collections Library)
031 */
032 @GwtCompatible(emulated = true)
033 public final class ObjectArrays {
034 private ObjectArrays() {}
035
036 /**
037 * Returns a new array of the given length with the specified component type.
038 *
039 * @param type the component type
040 * @param length the length of the new array
041 */
042 @SuppressWarnings("unchecked")
043 @GwtIncompatible("Array.newInstance(Class, int)")
044 public static <T> T[] newArray(Class<T> type, int length) {
045 return Platform.newArray(type, length);
046 }
047
048 /**
049 * Returns a new array of the given length with the same type as a reference
050 * array.
051 *
052 * @param reference any array of the desired type
053 * @param length the length of the new array
054 */
055 public static <T> T[] newArray(T[] reference, int length) {
056 return Platform.newArray(reference, length);
057 }
058
059 /**
060 * Returns a new array that contains the concatenated contents of two arrays.
061 *
062 * @param first the first array of elements to concatenate
063 * @param second the second array of elements to concatenate
064 * @param type the component type of the returned array
065 */
066 @GwtIncompatible("Array.newInstance(Class, int)")
067 public static <T> T[] concat(T[] first, T[] second, Class<T> type) {
068 T[] result = newArray(type, first.length + second.length);
069 Platform.unsafeArrayCopy(first, 0, result, 0, first.length);
070 Platform.unsafeArrayCopy(second, 0, result, first.length, second.length);
071 return result;
072 }
073
074 /**
075 * Returns a new array that prepends {@code element} to {@code array}.
076 *
077 * @param element the element to prepend to the front of {@code array}
078 * @param array the array of elements to append
079 * @return an array whose size is one larger than {@code array}, with
080 * {@code element} occupying the first position, and the
081 * elements of {@code array} occupying the remaining elements.
082 */
083 public static <T> T[] concat(@Nullable T element, T[] array) {
084 T[] result = newArray(array, array.length + 1);
085 result[0] = element;
086 Platform.unsafeArrayCopy(array, 0, result, 1, array.length);
087 return result;
088 }
089
090 /**
091 * Returns a new array that appends {@code element} to {@code array}.
092 *
093 * @param array the array of elements to prepend
094 * @param element the element to append to the end
095 * @return an array whose size is one larger than {@code array}, with
096 * the same contents as {@code array}, plus {@code element} occupying the
097 * last position.
098 */
099 public static <T> T[] concat(T[] array, @Nullable T element) {
100 T[] result = arraysCopyOf(array, array.length + 1);
101 result[array.length] = element;
102 return result;
103 }
104
105 /** GWT safe version of Arrays.copyOf. */
106 private static <T> T[] arraysCopyOf(T[] original, int newLength) {
107 T[] copy = newArray(original, newLength);
108 Platform.unsafeArrayCopy(
109 original, 0, copy, 0, Math.min(original.length, newLength));
110 return copy;
111 }
112
113 /**
114 * Returns an array containing all of the elements in the specified
115 * collection; the runtime type of the returned array is that of the specified
116 * array. If the collection fits in the specified array, it is returned
117 * therein. Otherwise, a new array is allocated with the runtime type of the
118 * specified array and the size of the specified collection.
119 *
120 * <p>If the collection fits in the specified array with room to spare (i.e.,
121 * the array has more elements than the collection), the element in the array
122 * immediately following the end of the collection is set to null. This is
123 * useful in determining the length of the collection <i>only</i> if the
124 * caller knows that the collection does not contain any null elements.
125 *
126 * <p>This method returns the elements in the order they are returned by the
127 * collection's iterator.
128 *
129 * <p>TODO(kevinb): support concurrently modified collections?
130 *
131 * @param c the collection for which to return an array of elements
132 * @param array the array in which to place the collection elements
133 * @throws ArrayStoreException if the runtime type of the specified array is
134 * not a supertype of the runtime type of every element in the specified
135 * collection
136 */
137 static <T> T[] toArrayImpl(Collection<?> c, T[] array) {
138 int size = c.size();
139 if (array.length < size) {
140 array = newArray(array, size);
141 }
142 fillArray(c, array);
143 if (array.length > size) {
144 array[size] = null;
145 }
146 return array;
147 }
148
149 /**
150 * Returns an array containing all of the elements in the specified
151 * collection. This method returns the elements in the order they are returned
152 * by the collection's iterator. The returned array is "safe" in that no
153 * references to it are maintained by the collection. The caller is thus free
154 * to modify the returned array.
155 *
156 * <p>This method assumes that the collection size doesn't change while the
157 * method is running.
158 *
159 * <p>TODO(kevinb): support concurrently modified collections?
160 *
161 * @param c the collection for which to return an array of elements
162 */
163 static Object[] toArrayImpl(Collection<?> c) {
164 return fillArray(c, new Object[c.size()]);
165 }
166
167 private static Object[] fillArray(Iterable<?> elements, Object[] array) {
168 int i = 0;
169 for (Object element : elements) {
170 array[i++] = element;
171 }
172 return array;
173 }
174
175 /**
176 * Swaps {@code array[i]} with {@code array[j]}.
177 */
178 static void swap(Object[] array, int i, int j) {
179 Object temp = array[i];
180 array[i] = array[j];
181 array[j] = temp;
182 }
183 }