1*f585d8a3SJacky Wang /* 2*f585d8a3SJacky Wang * Copyright (C) 2014 The Dagger Authors. 3*f585d8a3SJacky Wang * 4*f585d8a3SJacky Wang * Licensed under the Apache License, Version 2.0 (the "License"); 5*f585d8a3SJacky Wang * you may not use this file except in compliance with the License. 6*f585d8a3SJacky Wang * You may obtain a copy of the License at 7*f585d8a3SJacky Wang * 8*f585d8a3SJacky Wang * http://www.apache.org/licenses/LICENSE-2.0 9*f585d8a3SJacky Wang * 10*f585d8a3SJacky Wang * Unless required by applicable law or agreed to in writing, software 11*f585d8a3SJacky Wang * distributed under the License is distributed on an "AS IS" BASIS, 12*f585d8a3SJacky Wang * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13*f585d8a3SJacky Wang * See the License for the specific language governing permissions and 14*f585d8a3SJacky Wang * limitations under the License. 15*f585d8a3SJacky Wang */ 16*f585d8a3SJacky Wang 17*f585d8a3SJacky Wang package dagger.internal; 18*f585d8a3SJacky Wang 19*f585d8a3SJacky Wang import java.util.ArrayList; 20*f585d8a3SJacky Wang import java.util.Collections; 21*f585d8a3SJacky Wang import java.util.HashSet; 22*f585d8a3SJacky Wang import java.util.LinkedHashMap; 23*f585d8a3SJacky Wang import java.util.List; 24*f585d8a3SJacky Wang import java.util.Set; 25*f585d8a3SJacky Wang 26*f585d8a3SJacky Wang /** 27*f585d8a3SJacky Wang * Collection utility methods in service of Dagger internal classes. <em>Do not use</em> in client 28*f585d8a3SJacky Wang * code. 29*f585d8a3SJacky Wang */ 30*f585d8a3SJacky Wang public final class DaggerCollections { 31*f585d8a3SJacky Wang /** 32*f585d8a3SJacky Wang * The maximum value for a signed 32-bit integer that is equal to a power of 2. 33*f585d8a3SJacky Wang */ 34*f585d8a3SJacky Wang private static final int MAX_POWER_OF_TWO = 1 << (Integer.SIZE - 2); 35*f585d8a3SJacky Wang DaggerCollections()36*f585d8a3SJacky Wang private DaggerCollections() {} 37*f585d8a3SJacky Wang 38*f585d8a3SJacky Wang /** 39*f585d8a3SJacky Wang * Returns a new list that is pre-sized to {@code size}, or {@link Collections#emptyList()} if 40*f585d8a3SJacky Wang * empty. The list returned is never intended to grow beyond {@code size}, so adding to a list 41*f585d8a3SJacky Wang * when the size is 0 is an error. 42*f585d8a3SJacky Wang */ presizedList(int size)43*f585d8a3SJacky Wang public static <T> List<T> presizedList(int size) { 44*f585d8a3SJacky Wang if (size == 0) { 45*f585d8a3SJacky Wang return Collections.emptyList(); 46*f585d8a3SJacky Wang } 47*f585d8a3SJacky Wang return new ArrayList<T>(size); 48*f585d8a3SJacky Wang } 49*f585d8a3SJacky Wang 50*f585d8a3SJacky Wang /** 51*f585d8a3SJacky Wang * Returns true if at least one pair of items in {@code list} are equals. 52*f585d8a3SJacky Wang */ hasDuplicates(List<?> list)53*f585d8a3SJacky Wang public static boolean hasDuplicates(List<?> list) { 54*f585d8a3SJacky Wang if (list.size() < 2) { 55*f585d8a3SJacky Wang return false; 56*f585d8a3SJacky Wang } 57*f585d8a3SJacky Wang Set<Object> asSet = new HashSet<Object>(list); 58*f585d8a3SJacky Wang return list.size() != asSet.size(); 59*f585d8a3SJacky Wang } 60*f585d8a3SJacky Wang 61*f585d8a3SJacky Wang /** 62*f585d8a3SJacky Wang * Creates a {@link HashSet} instance, with a high enough "intial capcity" that it <em>should</em> 63*f585d8a3SJacky Wang * hold {@code expectedSize} elements without growth. 64*f585d8a3SJacky Wang */ newHashSetWithExpectedSize(int expectedSize)65*f585d8a3SJacky Wang static <T> HashSet<T> newHashSetWithExpectedSize(int expectedSize) { 66*f585d8a3SJacky Wang return new HashSet<T>(calculateInitialCapacity(expectedSize)); 67*f585d8a3SJacky Wang } 68*f585d8a3SJacky Wang 69*f585d8a3SJacky Wang /** 70*f585d8a3SJacky Wang * Creates a {@link LinkedHashMap} instance, with a high enough "initial capacity" that it 71*f585d8a3SJacky Wang * <em>should</em> hold {@code expectedSize} elements without growth. 72*f585d8a3SJacky Wang */ newLinkedHashMapWithExpectedSize(int expectedSize)73*f585d8a3SJacky Wang public static <K, V> LinkedHashMap<K, V> newLinkedHashMapWithExpectedSize(int expectedSize) { 74*f585d8a3SJacky Wang return new LinkedHashMap<K, V>(calculateInitialCapacity(expectedSize)); 75*f585d8a3SJacky Wang } 76*f585d8a3SJacky Wang calculateInitialCapacity(int expectedSize)77*f585d8a3SJacky Wang private static int calculateInitialCapacity(int expectedSize) { 78*f585d8a3SJacky Wang if (expectedSize < 3) { 79*f585d8a3SJacky Wang return expectedSize + 1; 80*f585d8a3SJacky Wang } 81*f585d8a3SJacky Wang if (expectedSize < MAX_POWER_OF_TWO) { 82*f585d8a3SJacky Wang // This is the calculation used in JDK8 to resize when a putAll 83*f585d8a3SJacky Wang // happens; it seems to be the most conservative calculation we 84*f585d8a3SJacky Wang // can make. 0.75 is the default load factor. 85*f585d8a3SJacky Wang return (int) (expectedSize / 0.75F + 1.0F); 86*f585d8a3SJacky Wang } 87*f585d8a3SJacky Wang return Integer.MAX_VALUE; // any large value 88*f585d8a3SJacky Wang } 89*f585d8a3SJacky Wang } 90