1 /* 2 * Copyright (C) 2018 The Android Open Source Project 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.android.permissioncontroller.permission.utils; 18 19 import android.util.ArraySet; 20 21 import androidx.annotation.NonNull; 22 import androidx.annotation.Nullable; 23 24 import java.util.Arrays; 25 import java.util.Collection; 26 import java.util.Collections; 27 import java.util.List; 28 import java.util.Set; 29 30 /** 31 * Utility methods for dealing with {@link java.util.Collection}s. 32 */ 33 public final class CollectionUtils { 34 CollectionUtils()35 private CollectionUtils() {} 36 37 /** 38 * Check whether a collection is {@code null} or empty. 39 * 40 * @param collection the collection to check 41 * 42 * @return whether the collection is {@code null} or empty 43 */ isEmpty(@ullable Collection<?> collection)44 public static boolean isEmpty(@Nullable Collection<?> collection) { 45 return collection == null || collection.isEmpty(); 46 } 47 48 /** 49 * Return the first element of a list, or {@code null} if the list is {@code null} or empty. 50 * 51 * @param <T> the class of the elements of the list 52 * @param list the list to get the first element 53 * 54 * @return the first element of the list, or {@code null} if the list is {@code null} or empty 55 */ 56 @Nullable firstOrNull(@ullable List<T> list)57 public static <T> T firstOrNull(@Nullable List<T> list) { 58 return !isEmpty(list) ? list.get(0) : null; 59 } 60 61 /** 62 * Remove all values in the array set that do <b>not</b> exist in the given collection. 63 * 64 * @param <T> the class of the elements to retain and of the {@code ArraySet} 65 * @param arraySet the {@code ArraySet} whose elements are to be removed or retained 66 * @param valuesToRetain the values to be used to determine which elements to retain 67 * 68 * @return {@code true} if any values were removed from the array set, {@code false} otherwise. 69 * 70 * @see ArraySet#retainAll(java.util.Collection) 71 */ 72 @SafeVarargs retainAll(ArraySet<T> arraySet, T... valuesToRetain)73 public static <T> boolean retainAll(ArraySet<T> arraySet, T... valuesToRetain) { 74 boolean removed = false; 75 for (int i = arraySet.size() - 1; i >= 0; i--) { 76 if (!ArrayUtils.contains(valuesToRetain, arraySet.valueAt(i))) { 77 arraySet.removeAt(i); 78 removed = true; 79 } 80 } 81 return removed; 82 } 83 84 /** 85 * Return a singleton list containing the element, or an empty list if the element is 86 * {@code null}. 87 * 88 * @param <T> the class of the element 89 * @param element the element to be put into the list 90 * 91 * @return a singleton list containing the element, or an empty list if the element is 92 * {@code null}. 93 */ 94 @NonNull singletonOrEmpty(@ullable T element)95 public static <T> List<T> singletonOrEmpty(@Nullable T element) { 96 return element != null ? Collections.singletonList(element) : Collections.emptyList(); 97 } 98 99 /** 100 * Returns whether a byte array is contained within a {@link Set} of byte arrays. Equality is 101 * not compared by reference, but by comparing the elements contained in the arrays. 102 * 103 * @param byteArrays a {@link Set} of byte arrays that will be searched 104 * @param otherByteArray byte array to be searched 105 * @return {@code true} if {@code byteArrays} contains a byte array with identical elements as 106 * {@code otherByteArray}. 107 */ contains(@onNull Set<byte[]> byteArrays, @NonNull byte[] otherByteArray)108 public static boolean contains(@NonNull Set<byte[]> byteArrays, 109 @NonNull byte[] otherByteArray) { 110 for (byte[] byteArray : byteArrays) { 111 if (Arrays.equals(byteArray, otherByteArray)) { 112 return true; 113 } 114 } 115 return false; 116 } 117 118 /** 119 * Returns whether a {@link Set} of byte arrays is contained within a {@link Set} of byte arrays 120 * as a subset. Equality for arrays is not compared by reference, but by comparing the elements 121 * contained in the arrays. 122 * 123 * @param byteArrays a {@link Set} of byte arrays which will be checked as a superset 124 * @param otherByteArrays a {@link Set} of byte arrays which be checked as a subset 125 * @return {@code true} if {@code byteArrays} contains all the arrays in {@code 126 * otherByteArrays}. 127 */ containsSubset( @onNull Set<byte[]> byteArrays, @NonNull Set<byte[]> otherByteArrays)128 public static boolean containsSubset( 129 @NonNull Set<byte[]> byteArrays, @NonNull Set<byte[]> otherByteArrays) { 130 for (byte[] byteArray : otherByteArrays) { 131 if (!contains(byteArrays, byteArray)) { 132 return false; 133 } 134 } 135 return true; 136 } 137 } 138