import java.lang.reflect.Field;
import java.util.LinkedHashMap;
/**
* Illustrate rehashing algorithm of Java's {@link LinkedHashMap} depending on its
* initial capacity and load factor.
*/
public class InitialCapacity {
private static final int NUM_OF_ELEM_MIN = 1;
private static final int NUM_OF_ELEM_MAX = 16;
/**
* Main method.
*
* @param args command line arguments (ignored)
* @throws ReflectiveOperationException in case of errors on accessing the map's internal table
*/
public static void main(String[] args) throws ReflectiveOperationException {
System.out.println("LinkedHashMap contructed with initialCapacity = number of expected elements:\n");
for (int numOfElem=NUM_OF_ELEM_MIN; numOfElem<=NUM_OF_ELEM_MAX; ++numOfElem) {
fillMap(numOfElem, numOfElem);
}
System.out.println("\nLinkedHashMap contructed with initialCapacity = number of expected elements / 0.75f + 1\n");
for (int numOfElem=NUM_OF_ELEM_MIN; numOfElem<=NUM_OF_ELEM_MAX; ++numOfElem) {
fillMap((int) (numOfElem/0.75f) + 1, numOfElem);
}
}
/**
* Creates a {@link LinkedHashMap} with initialCapacity, fills it with numOfElem and prints out
* its internal table size before and after filling.
*
* @param initialCapacity the initial capacity ({@link LinkedHashMap} constructor)
* @param numOfElem number of elements to be filled in
* @throws ReflectiveOperationException in case of errors on accessing the map's internal table
*/
private static void fillMap(final int initialCapacity, final int numOfElem) throws ReflectiveOperationException {
final LinkedHashMap map = new LinkedHashMap<>(initialCapacity);
// put first entry to initialize the internal table of the map
map.put(0, 0);
// internal size before filling
final int sizeBefore = getInternalTableSize(map);
// fill it
for (int i=0; i rehashed=%b",
initialCapacity, sizeBefore, numOfElem, sizeAfter, (sizeBefore!=sizeAfter)));
}
/**
* Accesses a {@link LinkedHashMap} and returns its internal table size.
*
* @param map the {@link LinkedHashMap} to access
* @return internal table size
* @throws ReflectiveOperationException in case of errors on accessing the map's internal table
*/
private static int getInternalTableSize(final LinkedHashMap,?> map) throws ReflectiveOperationException {
final Field f = map.getClass().getSuperclass().getDeclaredField("table");
f.setAccessible(true);
return ((Object[]) f.get(map)).length;
}
}