1090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson/*
21d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Copyright (C) 2007 The Guava Authors
3090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson *
4090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson * Licensed under the Apache License, Version 2.0 (the "License");
5090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson * you may not use this file except in compliance with the License.
6090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson * You may obtain a copy of the License at
7090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson *
8090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson * http://www.apache.org/licenses/LICENSE-2.0
9090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson *
10090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson * Unless required by applicable law or agreed to in writing, software
11090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson * distributed under the License is distributed on an "AS IS" BASIS,
12090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson * See the License for the specific language governing permissions and
14090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson * limitations under the License.
15090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson */
16090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson
17090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilsonpackage com.google.common.collect;
18090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson
19090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilsonimport com.google.common.annotations.GwtCompatible;
20090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson
21090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilsonimport java.util.Collection;
22090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson
23090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilsonimport javax.annotation.Nullable;
24090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson
25090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson/**
26090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson * Static utility methods pertaining to object arrays.
27090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson *
28090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson * @author Kevin Bourrillion
291d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @since 2.0 (imported from Google Collections Library)
30090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson */
311d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert@GwtCompatible(emulated = true)
32090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilsonpublic final class ObjectArrays {
33090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson  private ObjectArrays() {}
34090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson
35090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson  /**
36090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson   * Returns a new array of the given length with the same type as a reference
37090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson   * array.
38090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson   *
39090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson   * @param reference any array of the desired type
40090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson   * @param length the length of the new array
41090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson   */
42090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson  public static <T> T[] newArray(T[] reference, int length) {
43090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson    return Platform.newArray(reference, length);
44090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson  }
45090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson
46090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson  /**
47090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson   * Returns a new array that prepends {@code element} to {@code array}.
48090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson   *
49090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson   * @param element the element to prepend to the front of {@code array}
50090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson   * @param array the array of elements to append
51090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson   * @return an array whose size is one larger than {@code array}, with
52090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson   *     {@code element} occupying the first position, and the
53090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson   *     elements of {@code array} occupying the remaining elements.
54090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson   */
55090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson  public static <T> T[] concat(@Nullable T element, T[] array) {
56090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson    T[] result = newArray(array, array.length + 1);
57090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson    result[0] = element;
58bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor    Platform.unsafeArrayCopy(array, 0, result, 1, array.length);
59090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson    return result;
60090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson  }
61090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson
62090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson  /**
63090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson   * Returns a new array that appends {@code element} to {@code array}.
64090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson   *
65090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson   * @param array the array of elements to prepend
66090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson   * @param element the element to append to the end
67090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson   * @return an array whose size is one larger than {@code array}, with
68090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson   *     the same contents as {@code array}, plus {@code element} occupying the
69090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson   *     last position.
70090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson   */
71090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson  public static <T> T[] concat(T[] array, @Nullable T element) {
72090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson    T[] result = arraysCopyOf(array, array.length + 1);
73090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson    result[array.length] = element;
74090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson    return result;
75090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson  }
76090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson
77090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson  /** GWT safe version of Arrays.copyOf. */
781d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  static <T> T[] arraysCopyOf(T[] original, int newLength) {
79090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson    T[] copy = newArray(original, newLength);
80bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor    Platform.unsafeArrayCopy(
81090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson        original, 0, copy, 0, Math.min(original.length, newLength));
82090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson    return copy;
83090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson  }
84090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson
85090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson  /**
86090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson   * Returns an array containing all of the elements in the specified
87090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson   * collection; the runtime type of the returned array is that of the specified
88090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson   * array. If the collection fits in the specified array, it is returned
89090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson   * therein. Otherwise, a new array is allocated with the runtime type of the
90090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson   * specified array and the size of the specified collection.
91090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson   *
92090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson   * <p>If the collection fits in the specified array with room to spare (i.e.,
93090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson   * the array has more elements than the collection), the element in the array
941d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * immediately following the end of the collection is set to {@code null}.
951d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * This is useful in determining the length of the collection <i>only</i> if
961d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * the caller knows that the collection does not contain any null elements.
97090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson   *
98090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson   * <p>This method returns the elements in the order they are returned by the
99090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson   * collection's iterator.
100090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson   *
1011d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * <p>TODO(kevinb): support concurrently modified collections?
102090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson   *
103090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson   * @param c the collection for which to return an array of elements
104090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson   * @param array the array in which to place the collection elements
105090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson   * @throws ArrayStoreException if the runtime type of the specified array is
106090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson   *     not a supertype of the runtime type of every element in the specified
107090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson   *     collection
108090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson   */
109090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson  static <T> T[] toArrayImpl(Collection<?> c, T[] array) {
110090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson    int size = c.size();
111090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson    if (array.length < size) {
112090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson      array = newArray(array, size);
113090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson    }
114090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson    fillArray(c, array);
115090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson    if (array.length > size) {
116090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson      array[size] = null;
117090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson    }
118090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson    return array;
119090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson  }
120090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson
121090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson  /**
122090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson   * Returns an array containing all of the elements in the specified
123090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson   * collection. This method returns the elements in the order they are returned
124090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson   * by the collection's iterator. The returned array is "safe" in that no
125090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson   * references to it are maintained by the collection. The caller is thus free
126090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson   * to modify the returned array.
127090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson   *
128090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson   * <p>This method assumes that the collection size doesn't change while the
129090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson   * method is running.
130090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson   *
1311d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * <p>TODO(kevinb): support concurrently modified collections?
132090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson   *
133090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson   * @param c the collection for which to return an array of elements
134090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson   */
135090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson  static Object[] toArrayImpl(Collection<?> c) {
136090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson    return fillArray(c, new Object[c.size()]);
137090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson  }
138090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson
139090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson  private static Object[] fillArray(Iterable<?> elements, Object[] array) {
140090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson    int i = 0;
141090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson    for (Object element : elements) {
142090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson      array[i++] = element;
143090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson    }
144090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson    return array;
145090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson  }
1461d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
1471d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  /**
1481d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * Swaps {@code array[i]} with {@code array[j]}.
1491d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   */
1501d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  static void swap(Object[] array, int i, int j) {
1511d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    Object temp = array[i];
1521d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    array[i] = array[j];
1531d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    array[j] = temp;
1541d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
155090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson}
1561d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
157