-1

Looked some unofficial references, and want to confirm here my understanding is correct. Suppose we are adding new (unique) elements from time to time,

  1. ArrayList<T> will reallocate for memory since its memory needs to be continuous, when memory grow by newly inserted elements exceeds some threshold, reallocation of larger continuous memory space will happen, and existing elements will be moved to such newly allocated larger continuous memory space;
  2. HashSet<T> and HashMap<T> has no such issue since memory of them does not require to be continuous?

BTW, if some good articles on these areas, appreciate for refer as well.

regards, Lin

asked Nov 10, 2016 at 6:37
9
  • 1
    grepcode.com/file/repository.grepcode.com/java/root/jdk/openjdk/… seems to prove point1 Commented Nov 10, 2016 at 6:47
  • 1
    Read the javadoc. It says: When the number of entries in the hash table exceeds the product of the load factor and the current capacity, the hash table is rehashed (that is, internal data structures are rebuilt) so that the hash table has approximately twice the number of buckets Commented Nov 10, 2016 at 7:06
  • 1
    @LinMa The quote in my comment is an extract from the javadoc of HashMap. The link I have in my comment links to the documentation of HashMap. HashSet is implemented using a HashMap. You really need to take some time to read, carefully. Commented Nov 10, 2016 at 7:14
  • 1
    LinkedList is such a data structure. TreeSet and TreeMap, too. But you're overthinking things. Not reallocating doesn't mean that it's faster. And a Map and a List serve completely different purposes. If you need a List, use a List. If you need a Set, use a Set. If you need a Map, use a Map. Except for very specific use-cases, an ArrayList is faster (and uses less memory) than LinkedList. Commented Nov 10, 2016 at 7:20
  • 1
    stackoverflow.com/questions/200384/constant-amortized-time Commented Nov 10, 2016 at 20:08

1 Answer 1

2

If you checkout the sourcecode of add(E e) method in ArrayList<> in Java 8 (jre 1.8.0_71), it calls in for a method called ensureCapacityInternal(int minCapacity). i.e this method is called every time you add in an object to the ArrayList. This inturn calls in a series of methods and finally if the size of your ArrayList is smaller to hold the newly added element, it calls in a method called grow(int minCapacity). This method is as shown below:

/**
 * Increases the capacity to ensure that it can hold at least the
 * number of elements specified by the minimum capacity argument.
 *
 * @param minCapacity the desired minimum capacity
 */
 private void grow(int minCapacity) {
 // overflow-conscious code
 int oldCapacity = elementData.length;
 int newCapacity = oldCapacity + (oldCapacity >> 1);
 if (newCapacity - minCapacity < 0)
 newCapacity = minCapacity;
 if (newCapacity - MAX_ARRAY_SIZE > 0)
 newCapacity = hugeCapacity(minCapacity);
 // minCapacity is usually close to size, so this is a win:
 elementData = Arrays.copyOf(elementData, newCapacity);
 }

This will create a new array with size 1.5 times more than the initial one and copies all the elements from old array to the new one. This proves your point no. 1.

Coming back to your point no. 2, in case of HashMap<K,V>, they are a special type of array that hold key and value pairs. This array slots are called buckets. So, every object that you add into an HashMap, should override hashCode() and equals() method properly. When you call put(K key, V value) method, it inturn calls a method called putVal(int hash, K key, V value, boolean onlyIfAbsent, boolean evict) by calculating the #hash of the key hash(Object key) that you have passed. This hash indicates the bucket location where the Value object shoud go. Hence, the array here only indicates the address blocks where the objects goes in. This thread explains it in more detail. I hope this is what you were looking for.

answered Nov 10, 2016 at 7:33
3
  • Thanks sbaitmangalkar for such details, just want to clarify, for HashMap and HashSet, since no requirement to be in continuous memory space, there is no element reallocation happens, correct? Commented Nov 10, 2016 at 19:38
  • 1
    Yes, there is no requirement for continuous memory locations and there is no reallocation happening. But whenever the map gets dynamically resized, the existing entries are redistributed. Commented Nov 11, 2016 at 9:34
  • 1
    I'm glad that it helped you!! Commented Nov 14, 2016 at 5:31

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.