Skip to content

Latest commit

ย 

History

History

Folders and files

NameName
Last commit message
Last commit date

parent directory

..
ย 
ย 

README.md

JDK ๋ฒ„์ „ ๋ณ„ ArrayList ๊ธธ์ด ๊ฐ€๋ณ€ ํ™•์žฅ ๋ฐฉ๋ฒ• ์ฐจ์ด

Tistory ๋ธ”๋กœ๊ทธ ํฌ์ŠคํŒ… ๋ฐ”๋กœ๊ฐ€๊ธฐ

Java๋กœ ๊ฐœ๋ฐœํ•˜๋ฉด์„œ ๋ฐฐ์—ด์„ ์‚ฌ์šฉํ•ด์•ผ ํ•˜๋Š” ๊ฒฝ์šฐ Collection ํ”„๋ ˆ์ž„์›Œํฌ์˜ ArrayList ํด๋ž˜์Šค๋ฅผ ์‚ฌ์šฉํ•  ์ผ์ด ๊ต‰์žฅํžˆ ๋งŽ์Šต๋‹ˆ๋‹ค.

๋ฐฐ์—ด์€ ๊ณ ์ • ๊ธธ์ด ๋ฐ์ดํ„ฐ ๊ตฌ์กฐ๋ผ์„œ ์ตœ์ดˆ์— ํ• ๋‹นํ•ด๋†“์€ ๊ธธ์ด๋ฅผ ๋„˜์–ด๊ฐ€๋ฉด ์ง์ ‘ ๋” ํฐ ํฌ๊ธฐ์˜ ์ƒˆ๋กœ์šด ๋ฐฐ์—ด์„ ๋งŒ๋“ค์–ด์ค˜์•ผ ํ•˜๋Š” ๋ถˆํŽธํ•จ์ด ์žˆ๋Š” ๋ฐ˜๋ฉด, ArrayList๋Š” ์ƒˆ๋กœ์šด ๋ฐ์ดํ„ฐ๋ฅผ ์ถ”๊ฐ€ํ•  ๋•Œ ๋‚ด๋ถ€์ ์œผ๋กœ ๊ธธ์ด๋ฅผ ๊ฐ€๋ณ€์ ์œผ๋กœ ๊ด€๋ฆฌํ•ด์ฃผ๊ธฐ ๋•Œ๋ฌธ์— ๋” ํŽธ๋ฆฌํ•˜๊ฒŒ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๊ธฐ ๋•Œ๋ฌธ์ด์ฃ .

๊ทธ๋ ‡๋‹ค๋ฉด ์‹ค์ œ๋กœ ๋‚ด๋ถ€์—์„œ ์–ด๋–ค์‹์œผ๋กœ ArrayList์˜ ๊ธธ์ด๋ฅผ ๊ฐ€๋ณ€์ ์œผ๋กœ ๊ด€๋ฆฌํ• ๊นŒ์š”?

์ด๋Ÿฐ ArrayList ํด๋ž˜์Šค๋„ ๊ฐœ๋ฐœ์ž๋“ค์ด ์ž‘์„ฑํ•œ ์ฝ”๋“œ์ด๊ณ , JDK ๋ฒ„์ „์ด ์—…๋˜๋ฉด์„œ ๊ธฐ์กด ๊ตฌํ˜„ ์ฝ”๋“œ์˜ ๋ฌธ์ œ์ ์„ ๋ณด์™„ํ•˜๊ฑฐ๋‚˜ ๋” ํšจ์œจ์ด ์ข‹๊ฒŒ๋” ์—…๋ฐ์ดํŠธํ•ฉ๋‹ˆ๋‹ค.

๊ทธ๋ž˜์„œ JDK 6,7,8 ๋ฒ„์ „ ๊ฐ„ ArrayList ๊ตฌํ˜„ ๋ฐฉ์‹์— ์–ด๋–ค ์ฐจ์ด๊ฐ€ ์žˆ๋Š”์ง€ ์•Œ์•„๋ดค์Šต๋‹ˆ๋‹ค.

(์•„๋ž˜ JDK ๋ฒ„์ „ ๋ณ„ ์ฝ”๋“œ๋Š” ์ž˜๋ชป๋œ ์ดํ•ด๋ฅผ ๋ฐฉ์ง€ํ•˜๊ณ ์ž ์‹ค์ œ JDK ์†Œ์Šค์ฝ”๋“œ๋ฅผ ๊ทธ๋ž˜๋„ ์ฒจ๋ถ€ํ–ˆ์œผ๋‹ˆ ์ฐธ๊ณ  ๋ฐ”๋ž๋‹ˆ๋‹ค.)

JDK 6 - ArrayList Implementation

/**
 * Increases the capacity of this <tt>ArrayList</tt> instance, if
 * necessary, to ensure that it can hold at least the number of elements
 * specified by the minimum capacity argument.
 *
 * @param   minCapacity   the desired minimum capacity
 */
public void ensureCapacity(int minCapacity) {
    modCount++;
    int oldCapacity = elementData.length;
    if (minCapacity > oldCapacity) {
        Object oldData[] = elementData;
        int newCapacity = (oldCapacity * 3)/2 + 1;
        if (newCapacity < minCapacity)
            newCapacity = minCapacity;
        // minCapacity is usually close to size, so this is a win:
        elementData = Arrays.copyOf(elementData, newCapacity);
    }
}

/**
 * Appends the specified element to the end of this list.
 *
 * @param e element to be appended to this list
 * @return <tt>true</tt> (as specified by {@link Collection#add})
 */
public boolean add(E e) {
    ensureCapacity(size + 1);  // Increments modCount!!
    elementData[size++] = e;
    return true;
}

/**
 * Inserts the specified element at the specified position in this
 * list. Shifts the element currently at that position (if any) and
 * any subsequent elements to the right (adds one to their indices).
 *
 * @param index index at which the specified element is to be inserted
 * @param element element to be inserted
 * @throws IndexOutOfBoundsException {@inheritDoc}
 */
public void add(int index, E element) {
    rangeCheckForAdd(index);

    ensureCapacity(size+1);  // Increments modCount!!
    System.arraycopy(elementData, index, elementData, index + 1,
                        size - index);
    elementData[index] = element;
    size++;
}

JDK 6 - ArrayList ๊ตฌํ˜„ ๋ฐฉ์‹ ์„ค๋ช…

add ๋ฉ”์†Œ๋“œ์˜ ๋‚ด์šฉ์— ensureCapacity๊ฐ€ ArrayList์˜ ํ™•์žฅ ์—ฌ๋ถ€๋ฅผ ํ™•์ธํ•˜๊ณ  ์ž‘์—…ํ•˜๋Š” ๋ถ€๋ถ„์ด๊ธฐ ๋•Œ๋ฌธ์— ํ•œ๋ฒˆ ์‚ดํŽด๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

  1. oldCapacity์— ๊ธฐ์กด elementData์˜ ๊ธธ์ด ํ• ๋‹น
  2. ์ตœ์†Œ ํ•„์š” ๊ธธ์ด minCapacity๊ฐ€ oldCapactiy๋ณด๋‹ค ํฐ ๊ฒฝ์šฐ
    1. newCapacity๋ฅผ oldCapacity์— 3์„ ๊ณฑํ•œ ๋’ค 2๋กœ ๋‚˜๋ˆˆ ๋‹ค์Œ 1์„ ๋”ํ•œ ๊ฐ’(์•ฝ 1.5๋ฐฐ)์œผ๋กœ ์žก๋Š”๋‹ค.
    2. ๋งŒ์•ฝ ์ƒˆ๋กœ์šด newCapacity๋„ minCapacity๋ณด๋‹ค ์ž‘๋‹ค๋ฉด newCapacity๋ฅผ minCapacity๋กœ ์น˜ํ™˜ํ•œ๋‹ค.
    3. Arrays.copyOf()๋ฅผ ์ด์šฉํ•ด์„œ ๊ธฐ์กด elementData๋ฅผ newCapacity๋งŒํผ ๋ณต์‚ฌํ•œ๋‹ค.
  3. 2๋ฒˆ์˜ ๊ฒฝ์šฐ๊ฐ€ ์•„๋‹ˆ๋ผ๋ฉด ์•„๋ฌด ์ž‘์—…์„ ์•ˆํ•ด๋„ ๋˜๊ธฐ ๋•Œ๋ฌธ์— ํ•จ์ˆ˜ ์ข…๋ฃŒ.

JDK 6์—์„œ๋Š” ๋” ํฐ ArrayList๊ฐ€ ํ•„์š”ํ•œ ๊ฒฝ์šฐ ๊ณฑ์…ˆ๊ณผ ๋‚˜๋ˆ—์…ˆ ์—ฐ์‚ฐ์„ ํ†ตํ•ด ๊ธฐ์กด ๊ธธ์ด์—์„œ ์•ฝ 1.5๋ฐฐ๋งŒํผ์˜ ํฌ๊ธฐ๋กœ ํ™•์žฅํ•œ ์ƒˆ๋กœ์šด ๊ธธ์ด์˜ ArrayList๋ฅผ ์ƒ์„ฑํ•˜์—ฌ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

JDK 7 - ArrayList Implementation

/**
 * Appends the specified element to the end of this list.
 *
 * @param e element to be appended to this list
 * @return <tt>true</tt> (as specified by {@link Collection#add})
 */
public boolean add(E e) {
    ensureCapacityInternal(size + 1);  // Increments modCount!!
    elementData[size++] = e;
    return true;
}

/**
 * Inserts the specified element at the specified position in this
 * list. Shifts the element currently at that position (if any) and
 * any subsequent elements to the right (adds one to their indices).
 *
 * @param index index at which the specified element is to be inserted
 * @param element element to be inserted
 * @throws IndexOutOfBoundsException {@inheritDoc}
 */
public void add(int index, E element) {
    rangeCheckForAdd(index);

    ensureCapacityInternal(size + 1);  // Increments modCount!!
    System.arraycopy(elementData, index, elementData, index + 1,
                        size - index);
    elementData[index] = element;
    size++;
}

/**
 * Increases the capacity of this <tt>ArrayList</tt> instance, if
 * necessary, to ensure that it can hold at least the number of elements
 * specified by the minimum capacity argument.
 *
 * @param   minCapacity   the desired minimum capacity
 */
public void ensureCapacity(int minCapacity) {
    if (minCapacity > 0)
        ensureCapacityInternal(minCapacity);
}

private void ensureCapacityInternal(int minCapacity) {
    modCount++;
    // overflow-conscious code
    if (minCapacity - elementData.length > 0)
        grow(minCapacity);
}

/**
 * The maximum size of array to allocate.
 * Some VMs reserve some header words in an array.
 * Attempts to allocate larger arrays may result in
 * OutOfMemoryError: Requested array size exceeds VM limit
 */
private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8;

/**
 * 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);
}

private static int hugeCapacity(int minCapacity) {
    if (minCapacity < 0) // overflow
        throw new OutOfMemoryError();
    return (minCapacity > MAX_ARRAY_SIZE) ?
        Integer.MAX_VALUE :
        MAX_ARRAY_SIZE;
}

JDK 7 - ArrayList ๊ตฌํ˜„ ๋ฐฉ์‹ ์„ค๋ช…

add ๋ฉ”์†Œ๋“œ์˜ ๋‚ด์šฉ์— ensureCapacityInternal๋ฅผ ๋ณด๋ฉด modCount๋ฅผ ๋Š˜๋ ค์ค€ ๋’ค grow ๋ฉ”์†Œ๋“œ๋ฅผ ํ˜ธ์ถœํ•˜๋Š” ๊ฒƒ์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์ด grow ๋ฉ”์†Œ๋“œ๊ฐ€ ArrayList์˜ ํ™•์žฅ ์—ฌ๋ถ€๋ฅผ ํ™•์ธํ•˜๊ณ  ์ž‘์—…ํ•˜๋Š” ๋ถ€๋ถ„์ด๊ธฐ ๋•Œ๋ฌธ์— ํ•œ๋ฒˆ ์‚ดํŽด๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

  1. oldCapacity์— ๊ธฐ์กด elementData์˜ ๊ธธ์ด ํ• ๋‹น
  2. ์ตœ์†Œ ํ•„์š” ๊ธธ์ด minCapacity๊ฐ€ oldCapactiy๋ณด๋‹ค ํฐ ๊ฒฝ์šฐ
    1. newCapacity๋ฅผ oldCapacity์— oldCapacity๋ฅผ ๋น„ํŠธ์—ฐ์‚ฐ์„ ํ†ตํ•ด ์˜ค๋ฅธ์ชฝ์œผ๋กœ ํ•œ์นธ shiftํ•œ ๊ฐ’์„ ๋”ํ•œ ๋’ค ์ €์žฅํ•œ๋‹ค.
    2. ๋งˆ์ฐฌ๊ฐ€์ง€๋กœ ๋งŒ์•ฝ ์ƒˆ๋กœ์šด newCapacity๋„ minCapacity๋ณด๋‹ค ์ž‘๋‹ค๋ฉด newCapacity๋ฅผ minCapacity๋กœ ์น˜ํ™˜ํ•œ๋‹ค.
    3. ๋งŒ์•ฝ, newCapacity๊ฐ€ MAX_ARRAY_SIZE๋ณด๋‹ค ํฌ๋‹ค๋ฉด hugeCapacity(minCapacity)๋ฅผ ํ˜ธ์ถœํ•œ๋‹ค.
      1. hugeCapacity๋ฅผ ํ†ตํ•ด overflow์ธ ๊ฒฝ์šฐ OutOfMemoryError๋ฅผ ๋˜์ง€๊ณ , overflow๊ฐ€ ์•„๋‹Œ ๊ฒฝ์šฐ์—๋Š” minCapacity์˜ ๊ฐ’์— ๋”ฐ๋ผ MAX_ARRAY_SIZE ํ˜น์€ Integer.MAX_VALUE๋กœ ์ง€์ •ํ•œ๋‹ค.
    4. Arrays.copyOf()๋ฅผ ์ด์šฉํ•ด์„œ ๊ธฐ์กด elementData๋ฅผ newCapacity๋งŒํผ ๋ณต์‚ฌํ•œ๋‹ค.

JDK 7์—์„œ๋Š” JDK 6์™€ ๋‹ค๋ฅด๊ฒŒ ๋” ํฐ ArrayList๊ฐ€ ํ•„์š”ํ•œ ๊ฒฝ์šฐ ๊ณฑ์…ˆ๊ณผ ๋‚˜๋ˆ—์…ˆ ์—ฐ์‚ฐ์„ ํ†ตํ•˜์ง€ ์•Š๊ณ , ๋” ๋น ๋ฅด๊ณ  ํšจ์œจ์ ์ธ ๋น„ํŠธ์—ฐ์‚ฐ์„ ํ™œ์šฉํ•˜๋Š” ๊ฒƒ์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

oldCapacity + (oldCapacity >> 1)์˜ ๋น„ํŠธ์—ฐ์‚ฐ ๋ถ€๋ถ„์„ ์‚ดํŽด๋ณด๋ฉด, oldCapacity์˜ 2์ง„์ˆ˜๋ฅผ ์˜ค๋ฅธ์ชฝ์œผ๋กœ 1๋งŒํผ shift ํ•˜์—ฌ 2^1๋งŒํผ ๋‚˜๋ˆ„๋Š” ๊ฒƒ๊ณผ ๋™์ผํ•œ ์—ฐ์‚ฐ์„ ์ˆ˜ํ–‰ํ•˜์—ฌ ๊ธฐ์กด ๊ธธ์ด์—์„œ ์•ฝ 1.5๋ฐฐ๋งŒํผ์˜ ํฌ๊ธฐ๋กœ ํ™•์žฅํ•œ ์ƒˆ๋กœ์šด ArrayList๋ฅผ ์ƒ์„ฑํ•˜๋Š” ๊ฒƒ์ด์ฃ .

์ถ”๊ฐ€๋กœ, overflow์— ๋Œ€ํ•œ exception handling์ด ์ถ”๊ฐ€๋œ ๊ฒƒ๋„ JDK 6์™€์˜ ์ฐจ์ด์ ์ž…๋‹ˆ๋‹ค.

JDK 8 - ArrayList Implementation

/**
* Appends the specified element to the end of this list.
*
* @param e element to be appended to this list
* @return <tt>true</tt> (as specified by {@link Collection#add})
*/
public boolean add(E e) {
    ensureCapacityInternal(size + 1);  // Increments modCount!!
    elementData[size++] = e;
    return true;
}

/**
 * Inserts the specified element at the specified position in this
 * list. Shifts the element currently at that position (if any) and
 * any subsequent elements to the right (adds one to their indices).
 *
 * @param index index at which the specified element is to be inserted
 * @param element element to be inserted
 * @throws IndexOutOfBoundsException {@inheritDoc}
 */
public void add(int index, E element) {
    rangeCheckForAdd(index);

    ensureCapacityInternal(size + 1);  // Increments modCount!!
    System.arraycopy(elementData, index, elementData, index + 1,
                        size - index);
    elementData[index] = element;
    size++;
}

/**
 * Increases the capacity of this <tt>ArrayList</tt> instance, if
 * necessary, to ensure that it can hold at least the number of elements
 * specified by the minimum capacity argument.
 *
 * @param   minCapacity   the desired minimum capacity
 */
public void ensureCapacity(int minCapacity) {
    int minExpand = (elementData != EMPTY_ELEMENTDATA)
        // any size if real element table
        ? 0
        // larger than default for empty table. It's already supposed to be
        // at default size.
        : DEFAULT_CAPACITY;

    if (minCapacity > minExpand) {
        ensureExplicitCapacity(minCapacity);
    }
}

private void ensureCapacityInternal(int minCapacity) {
    if (elementData == EMPTY_ELEMENTDATA) {
        minCapacity = Math.max(DEFAULT_CAPACITY, minCapacity);
    }

    ensureExplicitCapacity(minCapacity);
}

private void ensureExplicitCapacity(int minCapacity) {
    modCount++;

    // overflow-conscious code
    if (minCapacity - elementData.length > 0)
        grow(minCapacity);
}

/**
 * The maximum size of array to allocate.
 * Some VMs reserve some header words in an array.
 * Attempts to allocate larger arrays may result in
 * OutOfMemoryError: Requested array size exceeds VM limit
 */
private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8;

/**
 * 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);
}

JDK 8 - ArrayList ๊ตฌํ˜„ ๋ฐฉ์‹ ์„ค๋ช…

JDK 8์€ JDK 7๊ณผ ๋™์ผํ•˜๊ฒŒ ๋น„ํŠธ์—ฐ์‚ฐ์„ ํ†ตํ•ด ์‚ฌ์ด์ฆˆ๊ฐ€ ๋” ํฐ ArrayList๋ฅผ ๋งŒ๋“ค์–ด์ค๋‹ˆ๋‹ค.

JDK 7๊ณผ์˜ ์ฐจ์ด๋Š” elementData๊ฐ€ ArrayList ์ธ์Šคํ„ด์Šค ์ตœ์ดˆ ์ƒ์„ฑ ์‹œ ํ• ๋‹น๋˜๋Š” EMPTY_ELEMENTDATA์ธ ๊ฒฝ์šฐ, ์ธ์ž๋กœ ๋ฐ›์€ minCapacity์™€ DEFAULT_CAPACITY์˜ ๊ฐ’์ธ 10 ์ค‘ ๋” ํฐ ์ˆ˜๋ฅผ minCapacity์— ํ• ๋‹นํ•˜๋Š” ๋ถ€๋ถ„์ด ์ถ”๊ฐ€๋œ ์ ์ž…๋‹ˆ๋‹ค.


์ด๋ฒˆ ๊ธฐํšŒ๋กœ ์ •๋ง ๋งŽ์ด ์‚ฌ์šฉํ•˜๋Š” ArrayList์˜ ๊ธธ์ด๋ฅผ ์–ด๋–ป๊ฒŒ ๊ฐ€๋ณ€์ ์œผ๋กœ ๊ด€๋ฆฌํ•˜๋Š”์ง€ ์ƒ์„ธํ•˜๊ณ  ์‚ดํŽด๋ณด์•˜๊ณ , JDK ๋ฒ„์ „ ๋ณ„ ์ƒˆ๋กœ ์ถ”๊ฐ€๋œ ๋‚ด์šฉ๋“ค ์™ธ์—๋„ ๊ธฐ์กด์— ์ด๋ฏธ ์žˆ๋Š” ํด๋ž˜์Šค๋“ค์— ์–ด๋–ค ์ž‘์—…๋“ค์„ ํ•˜๋Š”์ง€ ์•Œ๊ฒŒ ๋˜์—ˆ์Šต๋‹ˆ๋‹ค.

๋น„ํŠธ์—ฐ์‚ฐ์— ๋Œ€ํ•ด๋Š” ์•Œ๊ณ  ์žˆ์—ˆ์ง€๋งŒ ์ด๋ ‡๊ฒŒ ์‹ค์ œ๋กœ ํ™œ์šฉ์ด ๋œ ๋ถ€๋ถ„์€ ์ฒ˜์Œ ๋ณด์•˜๋Š”๋ฐ, ์ด ์—ญ์‹œ ์ด๋ก ์œผ๋กœ๋งŒ ๋ฐฐ์› ๋˜ ๋‚ด์šฉ์„ ์‹ค์ œ ์‚ฌ๋ก€๋กœ ๋ณด๊ณ  ๊ทธ ํšจ์œจ์„ฑ์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ๋Š” ์ข‹์€ ๊ธฐํšŒ์˜€๋˜ ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค.

ํŠนํžˆ, ๋‚ด๋ถ€ ์†Œ์Šค์ฝ”๋“œ๋Š” ์ดํ•ดํ•˜๊ธฐ ์–ด๋ ต๋‹ค๋Š” ๋‘๋ ค์›€์ด ์žˆ์—ˆ๋Š”๋ฐ ์—ด์–ด์„œ ํ™•์ธํ•ด๋ณด๋‹ˆ ์‹ค์ œ๋กœ ๊ทธ๋ ‡์ง€๋„ ์•Š์•„ ์•ž์œผ๋กœ ํ•ญ์ƒ ์ด๋Ÿฐ ์‹์œผ๋กœ ๊นŠ์ด ๊ณต๋ถ€ํ•˜๋Š” ๋ฒ„๋ฆ‡์„ ๋“ค์ผ ์ƒ๊ฐ์ž…๋‹ˆ๋‹ค.