Coverage Summary for Class: ObjectArrays (com.google.common.collect)

Class Class, % Method, % Line, %
ObjectArrays 100% (1/1) 26.7% (4/15) 15.7% (8/51)


1 /* 2  * Copyright (C) 2007 The Guava Authors 3  * 4  * Licensed under the Apache License, Version 2.0 (the "License"); 5  * you may not use this file except in compliance with the License. 6  * You may obtain a copy of the License at 7  * 8  * http://www.apache.org/licenses/LICENSE-2.0 9  * 10  * Unless required by applicable law or agreed to in writing, software 11  * distributed under the License is distributed on an "AS IS" BASIS, 12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13  * See the License for the specific language governing permissions and 14  * limitations under the License. 15  */ 16  17 package com.google.common.collect; 18  19 import static com.google.common.base.Preconditions.checkPositionIndexes; 20  21 import com.google.common.annotations.GwtCompatible; 22 import com.google.common.annotations.GwtIncompatible; 23 import com.google.errorprone.annotations.CanIgnoreReturnValue; 24 import java.lang.reflect.Array; 25 import java.util.Arrays; 26 import java.util.Collection; 27 import org.checkerframework.checker.nullness.qual.Nullable; 28  29 /** 30  * Static utility methods pertaining to object arrays. 31  * 32  * @author Kevin Bourrillion 33  * @since 2.0 34  */ 35 @GwtCompatible(emulated = true) 36 public final class ObjectArrays { 37  38  private ObjectArrays() {} 39  40  /** 41  * Returns a new array of the given length with the specified component type. 42  * 43  * @param type the component type 44  * @param length the length of the new array 45  */ 46  @GwtIncompatible // Array.newInstance(Class, int) 47  @SuppressWarnings("unchecked") 48  public static <T> T[] newArray(Class<T> type, int length) { 49  return (T[]) Array.newInstance(type, length); 50  } 51  52  /** 53  * Returns a new array of the given length with the same type as a reference array. 54  * 55  * @param reference any array of the desired type 56  * @param length the length of the new array 57  */ 58  public static <T> T[] newArray(T[] reference, int length) { 59  return Platform.newArray(reference, length); 60  } 61  62  /** 63  * Returns a new array that contains the concatenated contents of two arrays. 64  * 65  * @param first the first array of elements to concatenate 66  * @param second the second array of elements to concatenate 67  * @param type the component type of the returned array 68  */ 69  @GwtIncompatible // Array.newInstance(Class, int) 70  public static <T> T[] concat(T[] first, T[] second, Class<T> type) { 71  T[] result = newArray(type, first.length + second.length); 72  System.arraycopy(first, 0, result, 0, first.length); 73  System.arraycopy(second, 0, result, first.length, second.length); 74  return result; 75  } 76  77  /** 78  * Returns a new array that prepends {@code element} to {@code array}. 79  * 80  * @param element the element to prepend to the front of {@code array} 81  * @param array the array of elements to append 82  * @return an array whose size is one larger than {@code array}, with {@code element} occupying 83  * the first position, and the elements of {@code array} occupying the remaining elements. 84  */ 85  public static <T> T[] concat(@Nullable T element, T[] array) { 86  T[] result = newArray(array, array.length + 1); 87  result[0] = element; 88  System.arraycopy(array, 0, result, 1, array.length); 89  return result; 90  } 91  92  /** 93  * Returns a new array that appends {@code element} to {@code array}. 94  * 95  * @param array the array of elements to prepend 96  * @param element the element to append to the end 97  * @return an array whose size is one larger than {@code array}, with the same contents as {@code 98  * array}, plus {@code element} occupying the last position. 99  */ 100  public static <T> T[] concat(T[] array, @Nullable T element) { 101  T[] result = Arrays.copyOf(array, array.length + 1); 102  result[array.length] = element; 103  return result; 104  } 105  106  /** 107  * Returns an array containing all of the elements in the specified collection; the runtime type 108  * of the returned array is that of the specified array. If the collection fits in the specified 109  * array, it is returned therein. Otherwise, a new array is allocated with the runtime type of the 110  * specified array and the size of the specified collection. 111  * 112  * <p>If the collection fits in the specified array with room to spare (i.e., the array has more 113  * elements than the collection), the element in the array immediately following the end of the 114  * collection is set to {@code null}. This is useful in determining the length of the collection 115  * <i>only</i> if the caller knows that the collection does not contain any null elements. 116  * 117  * <p>This method returns the elements in the order they are returned by the collection's 118  * iterator. 119  * 120  * <p>TODO(kevinb): support concurrently modified collections? 121  * 122  * @param c the collection for which to return an array of elements 123  * @param array the array in which to place the collection elements 124  * @throws ArrayStoreException if the runtime type of the specified array is not a supertype of 125  * the runtime type of every element in the specified collection 126  */ 127  static <T> T[] toArrayImpl(Collection<?> c, T[] array) { 128  int size = c.size(); 129  if (array.length < size) { 130  array = newArray(array, size); 131  } 132  fillArray(c, array); 133  if (array.length > size) { 134  array[size] = null; 135  } 136  return array; 137  } 138  139  /** 140  * Implementation of {@link Collection#toArray(Object[])} for collections backed by an object 141  * array. the runtime type of the returned array is that of the specified array. If the collection 142  * fits in the specified array, it is returned therein. Otherwise, a new array is allocated with 143  * the runtime type of the specified array and the size of the specified collection. 144  * 145  * <p>If the collection fits in the specified array with room to spare (i.e., the array has more 146  * elements than the collection), the element in the array immediately following the end of the 147  * collection is set to {@code null}. This is useful in determining the length of the collection 148  * <i>only</i> if the caller knows that the collection does not contain any null elements. 149  */ 150  static <T> T[] toArrayImpl(Object[] src, int offset, int len, T[] dst) { 151  checkPositionIndexes(offset, offset + len, src.length); 152  if (dst.length < len) { 153  dst = newArray(dst, len); 154  } else if (dst.length > len) { 155  dst[len] = null; 156  } 157  System.arraycopy(src, offset, dst, 0, len); 158  return dst; 159  } 160  161  /** 162  * Returns an array containing all of the elements in the specified collection. This method 163  * returns the elements in the order they are returned by the collection's iterator. The returned 164  * array is "safe" in that no references to it are maintained by the collection. The caller is 165  * thus free to modify the returned array. 166  * 167  * <p>This method assumes that the collection size doesn't change while the method is running. 168  * 169  * <p>TODO(kevinb): support concurrently modified collections? 170  * 171  * @param c the collection for which to return an array of elements 172  */ 173  static Object[] toArrayImpl(Collection<?> c) { 174  return fillArray(c, new Object[c.size()]); 175  } 176  177  /** 178  * Returns a copy of the specified subrange of the specified array that is literally an Object[], 179  * and not e.g. a {@code String[]}. 180  */ 181  static Object[] copyAsObjectArray(Object[] elements, int offset, int length) { 182  checkPositionIndexes(offset, offset + length, elements.length); 183  if (length == 0) { 184  return new Object[0]; 185  } 186  Object[] result = new Object[length]; 187  System.arraycopy(elements, offset, result, 0, length); 188  return result; 189  } 190  191  @CanIgnoreReturnValue 192  private static Object[] fillArray(Iterable<?> elements, Object[] array) { 193  int i = 0; 194  for (Object element : elements) { 195  array[i++] = element; 196  } 197  return array; 198  } 199  200  /** Swaps {@code array[i]} with {@code array[j]}. */ 201  static void swap(Object[] array, int i, int j) { 202  Object temp = array[i]; 203  array[i] = array[j]; 204  array[j] = temp; 205  } 206  207  @CanIgnoreReturnValue 208  static Object[] checkElementsNotNull(Object... array) { 209  return checkElementsNotNull(array, array.length); 210  } 211  212  @CanIgnoreReturnValue 213  static Object[] checkElementsNotNull(Object[] array, int length) { 214  for (int i = 0; i < length; i++) { 215  checkElementNotNull(array[i], i); 216  } 217  return array; 218  } 219  220  // We do this instead of Preconditions.checkNotNull to save boxing and array 221  // creation cost. 222  @CanIgnoreReturnValue 223  static Object checkElementNotNull(Object element, int index) { 224  if (element == null) { 225  throw new NullPointerException("at index " + index); 226  } 227  return element; 228  } 229 }