ArrayUtils.java revision aa43a4ba9f61504a22d10f2c6d233576791e7776
1b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik/* 2b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik * Copyright (C) 2006 The Android Open Source Project 3b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik * 4b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik * Licensed under the Apache License, Version 2.0 (the "License"); 5b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik * you may not use this file except in compliance with the License. 6b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik * You may obtain a copy of the License at 7b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik * 8b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik * http://www.apache.org/licenses/LICENSE-2.0 9b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik * 10b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik * Unless required by applicable law or agreed to in writing, software 11b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik * distributed under the License is distributed on an "AS IS" BASIS, 12b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik * See the License for the specific language governing permissions and 14b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik * limitations under the License. 15b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik */ 16b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik 17b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craikpackage com.android.internal.util; 18b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik 19d2dfd8f128b632ed99418ab2b32949c939a9a369Chris Craikimport android.annotation.NonNull; 20b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craikimport android.annotation.Nullable; 21b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craikimport android.util.ArraySet; 22766431aa57c16ece8842287a92b2e7208e3b8ac3Doris Liu 23b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craikimport dalvik.system.VMRuntime; 24b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik 25b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craikimport libcore.util.EmptyArray; 26b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik 27b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craikimport java.lang.reflect.Array; 28b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craikimport java.util.ArrayList; 29b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craikimport java.util.Arrays; 306f485569fa3d6047dcffd068aebf361e3598783cDerek Sollenbergerimport java.util.Collection; 31b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craikimport java.util.Collections; 32b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craikimport java.util.List; 33b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craikimport java.util.Objects; 34003cc3dec8e2a92e51086fbcd5ee1bb236efa701Chris Craik 35b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik/** 36b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik * ArrayUtils contains some methods that you can call to find out 37b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik * the most efficient increments by which to grow arrays. 386f485569fa3d6047dcffd068aebf361e3598783cDerek Sollenberger */ 39003cc3dec8e2a92e51086fbcd5ee1bb236efa701Chris Craikpublic class ArrayUtils { 40b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik private static final int CACHE_SIZE = 73; 41003cc3dec8e2a92e51086fbcd5ee1bb236efa701Chris Craik private static Object[] sCache = new Object[CACHE_SIZE]; 42b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik 43e4db79de127cfe961195f52907af8451026eaa20Chris Craik private ArrayUtils() { /* cannot be instantiated */ } 44b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik 45161f54b2d4160b8d3f3da9eba5746da5162e4821Chris Craik public static byte[] newUnpaddedByteArray(int minLen) { 46b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik return (byte[])VMRuntime.getRuntime().newUnpaddedArray(byte.class, minLen); 47b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik } 48b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik 49003cc3dec8e2a92e51086fbcd5ee1bb236efa701Chris Craik public static char[] newUnpaddedCharArray(int minLen) { 50b87eadda1818034ce03d85f30388384d1ac65916Chris Craik return (char[])VMRuntime.getRuntime().newUnpaddedArray(char.class, minLen); 51b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik } 52b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik 53b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik public static int[] newUnpaddedIntArray(int minLen) { 54003cc3dec8e2a92e51086fbcd5ee1bb236efa701Chris Craik return (int[])VMRuntime.getRuntime().newUnpaddedArray(int.class, minLen); 55003cc3dec8e2a92e51086fbcd5ee1bb236efa701Chris Craik } 56b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik 57003cc3dec8e2a92e51086fbcd5ee1bb236efa701Chris Craik public static boolean[] newUnpaddedBooleanArray(int minLen) { 58b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik return (boolean[])VMRuntime.getRuntime().newUnpaddedArray(boolean.class, minLen); 59b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik } 60b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik 61003cc3dec8e2a92e51086fbcd5ee1bb236efa701Chris Craik public static long[] newUnpaddedLongArray(int minLen) { 62b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik return (long[])VMRuntime.getRuntime().newUnpaddedArray(long.class, minLen); 63b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik } 64b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik 65b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik public static float[] newUnpaddedFloatArray(int minLen) { 66b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik return (float[])VMRuntime.getRuntime().newUnpaddedArray(float.class, minLen); 67b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik } 68b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik 69b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik public static Object[] newUnpaddedObjectArray(int minLen) { 70b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik return (Object[])VMRuntime.getRuntime().newUnpaddedArray(Object.class, minLen); 71b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik } 72b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik 73b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik @SuppressWarnings("unchecked") 74b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik public static <T> T[] newUnpaddedArray(Class<T> clazz, int minLen) { 75b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik return (T[])VMRuntime.getRuntime().newUnpaddedArray(clazz, minLen); 76b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik } 77b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik 786fe991e5e76f9af9dab960100d5768d96d5f4daaChris Craik /** 796fe991e5e76f9af9dab960100d5768d96d5f4daaChris Craik * Checks if the beginnings of two byte arrays are equal. 806fe991e5e76f9af9dab960100d5768d96d5f4daaChris Craik * 816fe991e5e76f9af9dab960100d5768d96d5f4daaChris Craik * @param array1 the first byte array 826fe991e5e76f9af9dab960100d5768d96d5f4daaChris Craik * @param array2 the second byte array 836fe991e5e76f9af9dab960100d5768d96d5f4daaChris Craik * @param length the number of bytes to check 846fe991e5e76f9af9dab960100d5768d96d5f4daaChris Craik * @return true if they're equal, false otherwise 856fe991e5e76f9af9dab960100d5768d96d5f4daaChris Craik */ 867df9ff2a08fd4bbd9b2e734a357cffcf64675df9John Reck public static boolean equals(byte[] array1, byte[] array2, int length) { 87b87eadda1818034ce03d85f30388384d1ac65916Chris Craik if (length < 0) { 887df9ff2a08fd4bbd9b2e734a357cffcf64675df9John Reck throw new IllegalArgumentException(); 896fe991e5e76f9af9dab960100d5768d96d5f4daaChris Craik } 906fe991e5e76f9af9dab960100d5768d96d5f4daaChris Craik 916fe991e5e76f9af9dab960100d5768d96d5f4daaChris Craik if (array1 == array2) { 926fe991e5e76f9af9dab960100d5768d96d5f4daaChris Craik return true; 93b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik } 94b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik if (array1 == null || array2 == null || array1.length < length || array2.length < length) { 95b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik return false; 96eecff56fed5dd5206acfbc5007b4912081b36d3bFlorin Malita } 97b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik for (int i = 0; i < length; i++) { 98b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik if (array1[i] != array2[i]) { 99b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik return false; 100b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik } 101b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik } 102b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik return true; 103b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik } 104b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik 105b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik /** 106b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik * Returns an empty array of the specified type. The intent is that 107b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik * it will return the same empty array every time to avoid reallocation, 108b87eadda1818034ce03d85f30388384d1ac65916Chris Craik * although this is not guaranteed. 109eecff56fed5dd5206acfbc5007b4912081b36d3bFlorin Malita */ 1106fe991e5e76f9af9dab960100d5768d96d5f4daaChris Craik @SuppressWarnings("unchecked") 111eecff56fed5dd5206acfbc5007b4912081b36d3bFlorin Malita public static <T> T[] emptyArray(Class<T> kind) { 112eecff56fed5dd5206acfbc5007b4912081b36d3bFlorin Malita if (kind == Object.class) { 1136fe991e5e76f9af9dab960100d5768d96d5f4daaChris Craik return (T[]) EmptyArray.OBJECT; 1146fe991e5e76f9af9dab960100d5768d96d5f4daaChris Craik } 1156fe991e5e76f9af9dab960100d5768d96d5f4daaChris Craik 1166fe991e5e76f9af9dab960100d5768d96d5f4daaChris Craik int bucket = (kind.hashCode() & 0x7FFFFFFF) % CACHE_SIZE; 1176fe991e5e76f9af9dab960100d5768d96d5f4daaChris Craik Object cache = sCache[bucket]; 1186fe991e5e76f9af9dab960100d5768d96d5f4daaChris Craik 1196fe991e5e76f9af9dab960100d5768d96d5f4daaChris Craik if (cache == null || cache.getClass().getComponentType() != kind) { 120b87eadda1818034ce03d85f30388384d1ac65916Chris Craik cache = Array.newInstance(kind, 0); 1216fe991e5e76f9af9dab960100d5768d96d5f4daaChris Craik sCache[bucket] = cache; 1226fe991e5e76f9af9dab960100d5768d96d5f4daaChris Craik 123b87eadda1818034ce03d85f30388384d1ac65916Chris Craik // Log.e("cache", "new empty " + kind.getName() + " at " + bucket); 1246fe991e5e76f9af9dab960100d5768d96d5f4daaChris Craik } 1256fe991e5e76f9af9dab960100d5768d96d5f4daaChris Craik 126b87eadda1818034ce03d85f30388384d1ac65916Chris Craik return (T[]) cache; 127b87eadda1818034ce03d85f30388384d1ac65916Chris Craik } 128b87eadda1818034ce03d85f30388384d1ac65916Chris Craik 129b87eadda1818034ce03d85f30388384d1ac65916Chris Craik /** 130b87eadda1818034ce03d85f30388384d1ac65916Chris Craik * Checks if given array is null or has zero elements. 131b87eadda1818034ce03d85f30388384d1ac65916Chris Craik */ 132eecff56fed5dd5206acfbc5007b4912081b36d3bFlorin Malita public static boolean isEmpty(@Nullable Collection<?> array) { 133b87eadda1818034ce03d85f30388384d1ac65916Chris Craik return array == null || array.isEmpty(); 1346fe991e5e76f9af9dab960100d5768d96d5f4daaChris Craik } 1356fe991e5e76f9af9dab960100d5768d96d5f4daaChris Craik 1366fe991e5e76f9af9dab960100d5768d96d5f4daaChris Craik /** 137b87eadda1818034ce03d85f30388384d1ac65916Chris Craik * Checks if given array is null or has zero elements. 1386fe991e5e76f9af9dab960100d5768d96d5f4daaChris Craik */ 1396fe991e5e76f9af9dab960100d5768d96d5f4daaChris Craik public static <T> boolean isEmpty(@Nullable T[] array) { 1406fe991e5e76f9af9dab960100d5768d96d5f4daaChris Craik return array == null || array.length == 0; 1416fe991e5e76f9af9dab960100d5768d96d5f4daaChris Craik } 1426fe991e5e76f9af9dab960100d5768d96d5f4daaChris Craik 1436fe991e5e76f9af9dab960100d5768d96d5f4daaChris Craik /** 144b87eadda1818034ce03d85f30388384d1ac65916Chris Craik * Checks if given array is null or has zero elements. 1456fe991e5e76f9af9dab960100d5768d96d5f4daaChris Craik */ 1466fe991e5e76f9af9dab960100d5768d96d5f4daaChris Craik public static boolean isEmpty(@Nullable int[] array) { 1476fe991e5e76f9af9dab960100d5768d96d5f4daaChris Craik return array == null || array.length == 0; 1486fe991e5e76f9af9dab960100d5768d96d5f4daaChris Craik } 149b87eadda1818034ce03d85f30388384d1ac65916Chris Craik 150b87eadda1818034ce03d85f30388384d1ac65916Chris Craik /** 1516fe991e5e76f9af9dab960100d5768d96d5f4daaChris Craik * Checks if given array is null or has zero elements. 152b87eadda1818034ce03d85f30388384d1ac65916Chris Craik */ 153b87eadda1818034ce03d85f30388384d1ac65916Chris Craik public static boolean isEmpty(@Nullable long[] array) { 154b87eadda1818034ce03d85f30388384d1ac65916Chris Craik return array == null || array.length == 0; 1556fe991e5e76f9af9dab960100d5768d96d5f4daaChris Craik } 1566fe991e5e76f9af9dab960100d5768d96d5f4daaChris Craik 1576fe991e5e76f9af9dab960100d5768d96d5f4daaChris Craik /** 158b87eadda1818034ce03d85f30388384d1ac65916Chris Craik * Checks if given array is null or has zero elements. 159b87eadda1818034ce03d85f30388384d1ac65916Chris Craik */ 160b87eadda1818034ce03d85f30388384d1ac65916Chris Craik public static boolean isEmpty(@Nullable byte[] array) { 161b87eadda1818034ce03d85f30388384d1ac65916Chris Craik return array == null || array.length == 0; 162b87eadda1818034ce03d85f30388384d1ac65916Chris Craik } 163b87eadda1818034ce03d85f30388384d1ac65916Chris Craik 164b87eadda1818034ce03d85f30388384d1ac65916Chris Craik /** 165b87eadda1818034ce03d85f30388384d1ac65916Chris Craik * Checks if given array is null or has zero elements. 166b87eadda1818034ce03d85f30388384d1ac65916Chris Craik */ 167b87eadda1818034ce03d85f30388384d1ac65916Chris Craik public static boolean isEmpty(@Nullable boolean[] array) { 168b87eadda1818034ce03d85f30388384d1ac65916Chris Craik return array == null || array.length == 0; 169b87eadda1818034ce03d85f30388384d1ac65916Chris Craik } 1707df9ff2a08fd4bbd9b2e734a357cffcf64675df9John Reck 171b87eadda1818034ce03d85f30388384d1ac65916Chris Craik /** 172b87eadda1818034ce03d85f30388384d1ac65916Chris Craik * Length of the given array or 0 if it's null. 173b87eadda1818034ce03d85f30388384d1ac65916Chris Craik */ 174b87eadda1818034ce03d85f30388384d1ac65916Chris Craik public static int size(@Nullable Object[] array) { 175b87eadda1818034ce03d85f30388384d1ac65916Chris Craik return array == null ? 0 : array.length; 176b87eadda1818034ce03d85f30388384d1ac65916Chris Craik } 177b87eadda1818034ce03d85f30388384d1ac65916Chris Craik 1787df9ff2a08fd4bbd9b2e734a357cffcf64675df9John Reck /** 179b87eadda1818034ce03d85f30388384d1ac65916Chris Craik * Checks that value is present as at least one of the elements of the array. 180b87eadda1818034ce03d85f30388384d1ac65916Chris Craik * @param array the array to check in 181b87eadda1818034ce03d85f30388384d1ac65916Chris Craik * @param value the value to check for 182b87eadda1818034ce03d85f30388384d1ac65916Chris Craik * @return true if the value is present in the array 183b87eadda1818034ce03d85f30388384d1ac65916Chris Craik */ 1846fe991e5e76f9af9dab960100d5768d96d5f4daaChris Craik public static <T> boolean contains(@Nullable T[] array, T value) { 1856fe991e5e76f9af9dab960100d5768d96d5f4daaChris Craik return indexOf(array, value) != -1; 186b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik } 187b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik 188b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik /** 189b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik * Return first index of {@code value} in {@code array}, or {@code -1} if 190b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik * not found. 191b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik */ 192b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik public static <T> int indexOf(@Nullable T[] array, T value) { 193b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik if (array == null) return -1; 194b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik for (int i = 0; i < array.length; i++) { 195b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik if (Objects.equals(array[i], value)) return i; 196b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik } 197b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik return -1; 198b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik } 199b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik 200b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik /** 201b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik * Test if all {@code check} items are contained in {@code array}. 202b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik */ 203b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik public static <T> boolean containsAll(@Nullable T[] array, T[] check) { 204b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik if (check == null) return true; 205b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik for (T checkItem : check) { 206b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik if (!contains(array, checkItem)) { 207b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik return false; 208b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik } 209b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik } 210b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik return true; 211b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik } 212b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik 213e29ce6f51d681af7649c0a7cddee97c471e43eb5Chris Craik /** 214b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik * Test if any {@code check} items are contained in {@code array}. 215b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik */ 216b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik public static <T> boolean containsAny(@Nullable T[] array, T[] check) { 217b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik if (check == null) return false; 218b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik for (T checkItem : check) { 219b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik if (contains(array, checkItem)) { 220b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik return true; 221b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik } 222b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik } 223b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik return false; 224b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik } 225b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik 226b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik public static boolean contains(@Nullable int[] array, int value) { 227b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik if (array == null) return false; 228b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik for (int element : array) { 229b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik if (element == value) { 230b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik return true; 231b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik } 232b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik } 233b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik return false; 234b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik } 235b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik 236b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik public static boolean contains(@Nullable long[] array, long value) { 237b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik if (array == null) return false; 238b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik for (long element : array) { 239b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik if (element == value) { 240b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik return true; 241b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik } 242b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik } 243b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik return false; 2444c3980b6e43cc7c0541f54b8e7e2d9d6108be622Chris Craik } 2454c3980b6e43cc7c0541f54b8e7e2d9d6108be622Chris Craik 2464c3980b6e43cc7c0541f54b8e7e2d9d6108be622Chris Craik public static boolean contains(@Nullable char[] array, char value) { 2474c3980b6e43cc7c0541f54b8e7e2d9d6108be622Chris Craik if (array == null) return false; 248b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik for (char element : array) { 249b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik if (element == value) { 250386aa031793bb037ec43b6cdbd8908c343cc86cbChris Craik return true; 251386aa031793bb037ec43b6cdbd8908c343cc86cbChris Craik } 252386aa031793bb037ec43b6cdbd8908c343cc86cbChris Craik } 253386aa031793bb037ec43b6cdbd8908c343cc86cbChris Craik return false; 254386aa031793bb037ec43b6cdbd8908c343cc86cbChris Craik } 255386aa031793bb037ec43b6cdbd8908c343cc86cbChris Craik 256386aa031793bb037ec43b6cdbd8908c343cc86cbChris Craik /** 257386aa031793bb037ec43b6cdbd8908c343cc86cbChris Craik * Test if all {@code check} items are contained in {@code array}. 258b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik */ 259386aa031793bb037ec43b6cdbd8908c343cc86cbChris Craik public static <T> boolean containsAll(@Nullable char[] array, char[] check) { 260386aa031793bb037ec43b6cdbd8908c343cc86cbChris Craik if (check == null) return true; 261386aa031793bb037ec43b6cdbd8908c343cc86cbChris Craik for (char checkItem : check) { 262386aa031793bb037ec43b6cdbd8908c343cc86cbChris Craik if (!contains(array, checkItem)) { 2637df9ff2a08fd4bbd9b2e734a357cffcf64675df9John Reck return false; 264386aa031793bb037ec43b6cdbd8908c343cc86cbChris Craik } 265386aa031793bb037ec43b6cdbd8908c343cc86cbChris Craik } 266e4db79de127cfe961195f52907af8451026eaa20Chris Craik return true; 267386aa031793bb037ec43b6cdbd8908c343cc86cbChris Craik } 268b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik 269a1717271caac5e8ea3808c331d4141ac01a42134Chris Craik public static long total(@Nullable long[] array) { 270a1717271caac5e8ea3808c331d4141ac01a42134Chris Craik long total = 0; 271a1717271caac5e8ea3808c331d4141ac01a42134Chris Craik if (array != null) { 272a1717271caac5e8ea3808c331d4141ac01a42134Chris Craik for (long value : array) { 273a1717271caac5e8ea3808c331d4141ac01a42134Chris Craik total += value; 2747df9ff2a08fd4bbd9b2e734a357cffcf64675df9John Reck } 275386aa031793bb037ec43b6cdbd8908c343cc86cbChris Craik } 276a1717271caac5e8ea3808c331d4141ac01a42134Chris Craik return total; 277e4db79de127cfe961195f52907af8451026eaa20Chris Craik } 278a1717271caac5e8ea3808c331d4141ac01a42134Chris Craik 279b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik public static int[] convertToIntArray(List<Integer> list) { 280a1717271caac5e8ea3808c331d4141ac01a42134Chris Craik int[] array = new int[list.size()]; 281b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik for (int i = 0; i < list.size(); i++) { 2827df9ff2a08fd4bbd9b2e734a357cffcf64675df9John Reck array[i] = list.get(i); 283b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik } 284b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik return array; 285e4db79de127cfe961195f52907af8451026eaa20Chris Craik } 286b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik 287b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik /** 288b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik * Adds value to given array if not already present, providing set-like 289b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik * behavior. 290b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik */ 291b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik @SuppressWarnings("unchecked") 2927a89600bac7ab889a5ba8a994c57d677de0e45d5Chris Craik public static @NonNull <T> T[] appendElement(Class<T> kind, @Nullable T[] array, T element) { 293b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik return appendElement(kind, array, element, false); 294b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik } 295b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik 296b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik /** 297b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik * Adds value to given array. 298b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik */ 299b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik @SuppressWarnings("unchecked") 300b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik public static @NonNull <T> T[] appendElement(Class<T> kind, @Nullable T[] array, T element, 301b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik boolean allowDuplicates) { 302b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik final T[] result; 303b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik final int end; 304b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik if (array != null) { 305b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik if (!allowDuplicates && contains(array, element)) return array; 306b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik end = array.length; 307b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik result = (T[])Array.newInstance(kind, end + 1); 308b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik System.arraycopy(array, 0, result, 0, end); 309b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik } else { 310b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik end = 0; 311b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik result = (T[])Array.newInstance(kind, 1); 312b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik } 313b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik result[end] = element; 314b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik return result; 3157df9ff2a08fd4bbd9b2e734a357cffcf64675df9John Reck } 316b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik 317b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik /** 318e4db79de127cfe961195f52907af8451026eaa20Chris Craik * Removes value from given array if present, providing set-like behavior. 319b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik */ 320b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik @SuppressWarnings("unchecked") 321b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik public static @Nullable <T> T[] removeElement(Class<T> kind, @Nullable T[] array, T element) { 322b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik if (array != null) { 323b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik if (!contains(array, element)) return array; 324b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik final int length = array.length; 325b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik for (int i = 0; i < length; i++) { 326b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik if (Objects.equals(array[i], element)) { 327b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik if (length == 1) { 328b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik return null; 329b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik } 330b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik T[] result = (T[])Array.newInstance(kind, length - 1); 331b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik System.arraycopy(array, 0, result, 0, i); 332b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik System.arraycopy(array, i + 1, result, i, length - i - 1); 333b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik return result; 334b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik } 335b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik } 336b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik } 337b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik return array; 338b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik } 339b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik 340b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik /** 341b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik * Adds value to given array. 342b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik */ 343b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik public static @NonNull int[] appendInt(@Nullable int[] cur, int val, 344b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik boolean allowDuplicates) { 345b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik if (cur == null) { 346b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik return new int[] { val }; 347b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik } 348b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik final int N = cur.length; 3492dbb4c46ee648c64bb977b6839374d73b5a605d9Chris Craik if (!allowDuplicates) { 3502dbb4c46ee648c64bb977b6839374d73b5a605d9Chris Craik for (int i = 0; i < N; i++) { 3512dbb4c46ee648c64bb977b6839374d73b5a605d9Chris Craik if (cur[i] == val) { 3522dbb4c46ee648c64bb977b6839374d73b5a605d9Chris Craik return cur; 3532dbb4c46ee648c64bb977b6839374d73b5a605d9Chris Craik } 3542dbb4c46ee648c64bb977b6839374d73b5a605d9Chris Craik } 3552dbb4c46ee648c64bb977b6839374d73b5a605d9Chris Craik } 3562dbb4c46ee648c64bb977b6839374d73b5a605d9Chris Craik int[] ret = new int[N + 1]; 3572dbb4c46ee648c64bb977b6839374d73b5a605d9Chris Craik System.arraycopy(cur, 0, ret, 0, N); 358b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik ret[N] = val; 359386aa031793bb037ec43b6cdbd8908c343cc86cbChris Craik return ret; 360268a9c0f29c16a64d5819c7dbe8b0633baedab83Chris Craik } 361268a9c0f29c16a64d5819c7dbe8b0633baedab83Chris Craik 362268a9c0f29c16a64d5819c7dbe8b0633baedab83Chris Craik /** 363268a9c0f29c16a64d5819c7dbe8b0633baedab83Chris Craik * Adds value to given array if not already present, providing set-like 364268a9c0f29c16a64d5819c7dbe8b0633baedab83Chris Craik * behavior. 365268a9c0f29c16a64d5819c7dbe8b0633baedab83Chris Craik */ 366268a9c0f29c16a64d5819c7dbe8b0633baedab83Chris Craik public static @NonNull int[] appendInt(@Nullable int[] cur, int val) { 367268a9c0f29c16a64d5819c7dbe8b0633baedab83Chris Craik return appendInt(cur, val, false); 368268a9c0f29c16a64d5819c7dbe8b0633baedab83Chris Craik } 369268a9c0f29c16a64d5819c7dbe8b0633baedab83Chris Craik 370268a9c0f29c16a64d5819c7dbe8b0633baedab83Chris Craik /** 371268a9c0f29c16a64d5819c7dbe8b0633baedab83Chris Craik * Removes value from given array if present, providing set-like behavior. 372268a9c0f29c16a64d5819c7dbe8b0633baedab83Chris Craik */ 3737df9ff2a08fd4bbd9b2e734a357cffcf64675df9John Reck public static @Nullable int[] removeInt(@Nullable int[] cur, int val) { 374268a9c0f29c16a64d5819c7dbe8b0633baedab83Chris Craik if (cur == null) { 375e4db79de127cfe961195f52907af8451026eaa20Chris Craik return null; 376268a9c0f29c16a64d5819c7dbe8b0633baedab83Chris Craik } 377268a9c0f29c16a64d5819c7dbe8b0633baedab83Chris Craik final int N = cur.length; 378268a9c0f29c16a64d5819c7dbe8b0633baedab83Chris Craik for (int i = 0; i < N; i++) { 379268a9c0f29c16a64d5819c7dbe8b0633baedab83Chris Craik if (cur[i] == val) { 380268a9c0f29c16a64d5819c7dbe8b0633baedab83Chris Craik int[] ret = new int[N - 1]; 381b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik if (i > 0) { 382268a9c0f29c16a64d5819c7dbe8b0633baedab83Chris Craik System.arraycopy(cur, 0, ret, 0, i); 383386aa031793bb037ec43b6cdbd8908c343cc86cbChris Craik } 384386aa031793bb037ec43b6cdbd8908c343cc86cbChris Craik if (i < (N - 1)) { 385b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik System.arraycopy(cur, i + 1, ret, i, N - i - 1); 386386aa031793bb037ec43b6cdbd8908c343cc86cbChris Craik } 387268a9c0f29c16a64d5819c7dbe8b0633baedab83Chris Craik return ret; 388268a9c0f29c16a64d5819c7dbe8b0633baedab83Chris Craik } 389268a9c0f29c16a64d5819c7dbe8b0633baedab83Chris Craik } 390268a9c0f29c16a64d5819c7dbe8b0633baedab83Chris Craik return cur; 391268a9c0f29c16a64d5819c7dbe8b0633baedab83Chris Craik } 392268a9c0f29c16a64d5819c7dbe8b0633baedab83Chris Craik 393268a9c0f29c16a64d5819c7dbe8b0633baedab83Chris Craik /** 394268a9c0f29c16a64d5819c7dbe8b0633baedab83Chris Craik * Removes value from given array if present, providing set-like behavior. 3957df9ff2a08fd4bbd9b2e734a357cffcf64675df9John Reck */ 396268a9c0f29c16a64d5819c7dbe8b0633baedab83Chris Craik public static @Nullable String[] removeString(@Nullable String[] cur, String val) { 397e4db79de127cfe961195f52907af8451026eaa20Chris Craik if (cur == null) { 398268a9c0f29c16a64d5819c7dbe8b0633baedab83Chris Craik return null; 399268a9c0f29c16a64d5819c7dbe8b0633baedab83Chris Craik } 400268a9c0f29c16a64d5819c7dbe8b0633baedab83Chris Craik final int N = cur.length; 401268a9c0f29c16a64d5819c7dbe8b0633baedab83Chris Craik for (int i = 0; i < N; i++) { 402b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik if (Objects.equals(cur[i], val)) { 4037df9ff2a08fd4bbd9b2e734a357cffcf64675df9John Reck String[] ret = new String[N - 1]; 404386aa031793bb037ec43b6cdbd8908c343cc86cbChris Craik if (i > 0) { 405386aa031793bb037ec43b6cdbd8908c343cc86cbChris Craik System.arraycopy(cur, 0, ret, 0, i); 406e4db79de127cfe961195f52907af8451026eaa20Chris Craik } 407386aa031793bb037ec43b6cdbd8908c343cc86cbChris Craik if (i < (N - 1)) { 408b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik System.arraycopy(cur, i + 1, ret, i, N - i - 1); 409386aa031793bb037ec43b6cdbd8908c343cc86cbChris Craik } 410b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik return ret; 411386aa031793bb037ec43b6cdbd8908c343cc86cbChris Craik } 412caa24184735a607e87077c73262a42acdea7b8fbChris Craik } 413caa24184735a607e87077c73262a42acdea7b8fbChris Craik return cur; 414caa24184735a607e87077c73262a42acdea7b8fbChris Craik } 415caa24184735a607e87077c73262a42acdea7b8fbChris Craik 416caa24184735a607e87077c73262a42acdea7b8fbChris Craik /** 417caa24184735a607e87077c73262a42acdea7b8fbChris Craik * Adds value to given array if not already present, providing set-like 418caa24184735a607e87077c73262a42acdea7b8fbChris Craik * behavior. 419caa24184735a607e87077c73262a42acdea7b8fbChris Craik */ 420caa24184735a607e87077c73262a42acdea7b8fbChris Craik public static @NonNull long[] appendLong(@Nullable long[] cur, long val) { 421caa24184735a607e87077c73262a42acdea7b8fbChris Craik if (cur == null) { 422b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik return new long[] { val }; 423386aa031793bb037ec43b6cdbd8908c343cc86cbChris Craik } 424b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik final int N = cur.length; 4257df9ff2a08fd4bbd9b2e734a357cffcf64675df9John Reck for (int i = 0; i < N; i++) { 426386aa031793bb037ec43b6cdbd8908c343cc86cbChris Craik if (cur[i] == val) { 427386aa031793bb037ec43b6cdbd8908c343cc86cbChris Craik return cur; 428e4db79de127cfe961195f52907af8451026eaa20Chris Craik } 429386aa031793bb037ec43b6cdbd8908c343cc86cbChris Craik } 430b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik long[] ret = new long[N + 1]; 431b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik System.arraycopy(cur, 0, ret, 0, N); 432766431aa57c16ece8842287a92b2e7208e3b8ac3Doris Liu ret[N] = val; 433766431aa57c16ece8842287a92b2e7208e3b8ac3Doris Liu return ret; 4347df9ff2a08fd4bbd9b2e734a357cffcf64675df9John Reck } 435766431aa57c16ece8842287a92b2e7208e3b8ac3Doris Liu 436766431aa57c16ece8842287a92b2e7208e3b8ac3Doris Liu /** 437766431aa57c16ece8842287a92b2e7208e3b8ac3Doris Liu * Removes value from given array if present, providing set-like behavior. 438766431aa57c16ece8842287a92b2e7208e3b8ac3Doris Liu */ 439766431aa57c16ece8842287a92b2e7208e3b8ac3Doris Liu public static @Nullable long[] removeLong(@Nullable long[] cur, long val) { 440766431aa57c16ece8842287a92b2e7208e3b8ac3Doris Liu if (cur == null) { 441b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik return null; 442b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik } 443eecff56fed5dd5206acfbc5007b4912081b36d3bFlorin Malita final int N = cur.length; 444b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik for (int i = 0; i < N; i++) { 445b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik if (cur[i] == val) { 446b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik long[] ret = new long[N - 1]; 447b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik if (i > 0) { 448b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik System.arraycopy(cur, 0, ret, 0, i); 449b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik } 450b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik if (i < (N - 1)) { 451b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik System.arraycopy(cur, i + 1, ret, i, N - i - 1); 452b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik } 453b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik return ret; 454b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik } 455b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik } 456b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik return cur; 457b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik } 458b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik 459b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik public static @Nullable long[] cloneOrNull(@Nullable long[] array) { 460b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik return (array != null) ? array.clone() : null; 461b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik } 462b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik 463b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik public static @Nullable <T> ArraySet<T> cloneOrNull(@Nullable ArraySet<T> array) { 464eecff56fed5dd5206acfbc5007b4912081b36d3bFlorin Malita return (array != null) ? new ArraySet<T>(array) : null; 465b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik } 466b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik 467b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik public static @NonNull <T> ArraySet<T> add(@Nullable ArraySet<T> cur, T val) { 468b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik if (cur == null) { 469b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik cur = new ArraySet<>(); 470386aa031793bb037ec43b6cdbd8908c343cc86cbChris Craik } 471b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik cur.add(val); 472b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik return cur; 473b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik } 474b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik 475b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik public static @Nullable <T> ArraySet<T> remove(@Nullable ArraySet<T> cur, T val) { 476b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik if (cur == null) { 477b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik return null; 478b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik } 479b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik cur.remove(val); 480eecff56fed5dd5206acfbc5007b4912081b36d3bFlorin Malita if (cur.isEmpty()) { 481b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik return null; 482b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik } else { 483b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik return cur; 484b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik } 4857df9ff2a08fd4bbd9b2e734a357cffcf64675df9John Reck } 486f09ff5aa57bff01cb17595fb7ca8e48d238a6acdChris Craik 487f09ff5aa57bff01cb17595fb7ca8e48d238a6acdChris Craik public static @NonNull <T> ArrayList<T> add(@Nullable ArrayList<T> cur, T val) { 488e4db79de127cfe961195f52907af8451026eaa20Chris Craik if (cur == null) { 489f09ff5aa57bff01cb17595fb7ca8e48d238a6acdChris Craik cur = new ArrayList<>(); 490f09ff5aa57bff01cb17595fb7ca8e48d238a6acdChris Craik } 491b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik cur.add(val); 492b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik return cur; 493386aa031793bb037ec43b6cdbd8908c343cc86cbChris Craik } 494b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik 495b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik public static @Nullable <T> ArrayList<T> remove(@Nullable ArrayList<T> cur, T val) { 496f09ff5aa57bff01cb17595fb7ca8e48d238a6acdChris Craik if (cur == null) { 4977df9ff2a08fd4bbd9b2e734a357cffcf64675df9John Reck return null; 498f09ff5aa57bff01cb17595fb7ca8e48d238a6acdChris Craik } 499f09ff5aa57bff01cb17595fb7ca8e48d238a6acdChris Craik cur.remove(val); 500e4db79de127cfe961195f52907af8451026eaa20Chris Craik if (cur.isEmpty()) { 501f09ff5aa57bff01cb17595fb7ca8e48d238a6acdChris Craik return null; 502f09ff5aa57bff01cb17595fb7ca8e48d238a6acdChris Craik } else { 503f09ff5aa57bff01cb17595fb7ca8e48d238a6acdChris Craik return cur; 504b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik } 505386aa031793bb037ec43b6cdbd8908c343cc86cbChris Craik } 506f09ff5aa57bff01cb17595fb7ca8e48d238a6acdChris Craik 507b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik public static <T> boolean contains(@Nullable Collection<T> cur, T val) { 508b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik return (cur != null) ? cur.contains(val) : false; 5097df9ff2a08fd4bbd9b2e734a357cffcf64675df9John Reck } 510f09ff5aa57bff01cb17595fb7ca8e48d238a6acdChris Craik 511f09ff5aa57bff01cb17595fb7ca8e48d238a6acdChris Craik public static @Nullable <T> T[] trimToSize(@Nullable T[] array, int size) { 512e4db79de127cfe961195f52907af8451026eaa20Chris Craik if (array == null || size == 0) { 513f09ff5aa57bff01cb17595fb7ca8e48d238a6acdChris Craik return null; 514b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik } else if (array.length == size) { 515b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik return array; 516b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik } else { 517a1717271caac5e8ea3808c331d4141ac01a42134Chris Craik return Arrays.copyOf(array, size); 518b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik } 519b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik } 520a1717271caac5e8ea3808c331d4141ac01a42134Chris Craik 521a1717271caac5e8ea3808c331d4141ac01a42134Chris Craik /** 522a1717271caac5e8ea3808c331d4141ac01a42134Chris Craik * Returns true if the two ArrayLists are equal with respect to the objects they contain. 523a1717271caac5e8ea3808c331d4141ac01a42134Chris Craik * The objects must be in the same order and be reference equal (== not .equals()). 52415c3f19a445b8df575911a16e8a6dba755a084b5Chris Craik */ 5257df9ff2a08fd4bbd9b2e734a357cffcf64675df9John Reck public static <T> boolean referenceEquals(ArrayList<T> a, ArrayList<T> b) { 526a1717271caac5e8ea3808c331d4141ac01a42134Chris Craik if (a == b) { 527a1717271caac5e8ea3808c331d4141ac01a42134Chris Craik return true; 528e4db79de127cfe961195f52907af8451026eaa20Chris Craik } 529a1717271caac5e8ea3808c331d4141ac01a42134Chris Craik 530a1717271caac5e8ea3808c331d4141ac01a42134Chris Craik final int sizeA = a.size(); 531b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik final int sizeB = b.size(); 532a1717271caac5e8ea3808c331d4141ac01a42134Chris Craik if (a == null || b == null || sizeA != sizeB) { 533d7448e65e243754f31890baef29dff187dc2e5e5Chris Craik return false; 534b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik } 535d7448e65e243754f31890baef29dff187dc2e5e5Chris Craik 536d7448e65e243754f31890baef29dff187dc2e5e5Chris Craik boolean diff = false; 5377df9ff2a08fd4bbd9b2e734a357cffcf64675df9John Reck for (int i = 0; i < sizeA && !diff; i++) { 538d7448e65e243754f31890baef29dff187dc2e5e5Chris Craik diff |= a.get(i) != b.get(i); 5394c3980b6e43cc7c0541f54b8e7e2d9d6108be622Chris Craik } 540d7448e65e243754f31890baef29dff187dc2e5e5Chris Craik return !diff; 541b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik } 542b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik 543b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik /** 5447df9ff2a08fd4bbd9b2e734a357cffcf64675df9John Reck * Removes elements that match the predicate in an efficient way that alters the order of 5455430ab220b231a96b71c3e030d0303d9ce008b05Chris Craik * elements in the collection. This should only be used if order is not important. 546b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik * @param collection The ArrayList from which to remove elements. 547e4db79de127cfe961195f52907af8451026eaa20Chris Craik * @param predicate The predicate that each element is tested against. 548b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik * @return the number of elements removed. 549b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik */ 550e29ce6f51d681af7649c0a7cddee97c471e43eb5Chris Craik public static <T> int unstableRemoveIf(@Nullable ArrayList<T> collection, 551b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik @NonNull java.util.function.Predicate<T> predicate) { 55254fa17f667c285a5c9225e238c8132dfe830ef36Chris Craik if (collection == null) { 5537df9ff2a08fd4bbd9b2e734a357cffcf64675df9John Reck return 0; 55454fa17f667c285a5c9225e238c8132dfe830ef36Chris Craik } 555b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik 556e4db79de127cfe961195f52907af8451026eaa20Chris Craik final int size = collection.size(); 557b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik int leftIdx = 0; 558b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik int rightIdx = size - 1; 5591367d2550ebce40f45b16dc651bc3d8d22930801Chris Craik while (leftIdx <= rightIdx) { 5601367d2550ebce40f45b16dc651bc3d8d22930801Chris Craik // Find the next element to remove moving left to right. 561b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik while (leftIdx < size && !predicate.test(collection.get(leftIdx))) { 5621367d2550ebce40f45b16dc651bc3d8d22930801Chris Craik leftIdx++; 5631367d2550ebce40f45b16dc651bc3d8d22930801Chris Craik } 5641367d2550ebce40f45b16dc651bc3d8d22930801Chris Craik 565b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik // Find the next element to keep moving right to left. 5661367d2550ebce40f45b16dc651bc3d8d22930801Chris Craik while (rightIdx > leftIdx && predicate.test(collection.get(rightIdx))) { 5671367d2550ebce40f45b16dc651bc3d8d22930801Chris Craik rightIdx--; 5681367d2550ebce40f45b16dc651bc3d8d22930801Chris Craik } 5691367d2550ebce40f45b16dc651bc3d8d22930801Chris Craik 570b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik if (leftIdx >= rightIdx) { 571b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik // Done. 572b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik break; 573d2dfd8f128b632ed99418ab2b32949c939a9a369Chris Craik } 574d2dfd8f128b632ed99418ab2b32949c939a9a369Chris Craik 575d2dfd8f128b632ed99418ab2b32949c939a9a369Chris Craik Collections.swap(collection, leftIdx, rightIdx); 576d2dfd8f128b632ed99418ab2b32949c939a9a369Chris Craik leftIdx++; 577d2dfd8f128b632ed99418ab2b32949c939a9a369Chris Craik rightIdx--; 578d2dfd8f128b632ed99418ab2b32949c939a9a369Chris Craik } 579d2dfd8f128b632ed99418ab2b32949c939a9a369Chris Craik 580d2dfd8f128b632ed99418ab2b32949c939a9a369Chris Craik // leftIdx is now at the end. 5817df9ff2a08fd4bbd9b2e734a357cffcf64675df9John Reck for (int i = size - 1; i >= leftIdx; i--) { 582d2dfd8f128b632ed99418ab2b32949c939a9a369Chris Craik collection.remove(i); 583d2dfd8f128b632ed99418ab2b32949c939a9a369Chris Craik } 584e4db79de127cfe961195f52907af8451026eaa20Chris Craik return size - leftIdx; 585d2dfd8f128b632ed99418ab2b32949c939a9a369Chris Craik } 586d2dfd8f128b632ed99418ab2b32949c939a9a369Chris Craik} 587d2dfd8f128b632ed99418ab2b32949c939a9a369Chris Craik