ArrayList๋
ArrayList๋ ๋ฐฐ์ด๊ณผ ์ ์ฌํ๋ฉฐ, List ์ธํฐํ์ด์ค๋ฅผ ๊ตฌํํ ๊ฒ์ด๋ค. ๊ธฐ๋ณธ์ ์ผ๋ก ๊ฐ ๋ฐ์ดํฐ์ ์์ฐจ์ ์ผ๋ก ์ ๊ทผ ๊ฐ๋ฅํ ์ฐ์๋ ์๋ฃ๊ตฌ์กฐ์ด๋ค.
ArrayList์ ํน์ง
- ์ด๊ธฐํํ ๋ ํฌ๊ธฐ๋ฅผ ์ง์ ํ ํ์๊ฐ ์๋ค. ๋ฐฐ์ด์ ํฌ๊ธฐ๊ฐ ๊ณ ์ ๋์ด ์์ง๋ง, ArrayList๋ ์ฌ์ด์ฆ๊ฐ ๋์ ์ผ๋ก ํ ๋น๋๋ ๋ฐฐ์ด์ด๋ค.
- ์ฐธ์กฐ ํ์ (reference type)๋ง ์์๋ก ์ ์ฅํ ์ ์๋ค.
- ๋ฐ์ดํฐ ์ค๋ณต์ด ๊ฐ๋ฅํ๋ฉฐ, null ๊ฐ๋ ํ์ฉํ๋ค.
- ์๋ฃ๋ฅผ ๋๋์ผ๋ก ์ถ๊ฐํ๊ฑฐ๋ ์ญ์ ํ๋ฉด ๋ด๋ถ ์ฒ๋ฆฌ ์์ ์ด ๋์ด๋์ ์ฑ๋ฅ์ด ๋จ์ด์ง ์ ์๋ค.
ArrayList์ ์ฃผ์ ๋ฉ์๋
| ๋ฉ์๋ | ์ค๋ช |
| boolean add(E e) | ์ง์ ๋ ์ ๋ค๋ฆญ ํ์ ๋ฐ์ดํฐ๋ฅผ ์ถ๊ฐํ๋ค. |
| void add(int index, E element) | ํน์ ์ธ๋ฑ์ค ์์น์ ๋ฐ์ดํฐ๋ฅผ ์ถ๊ฐํ๋ค. |
| boolean addAll(Collection<? extends E> c) | Collection์ ํ์ฌ ArrayList์ ๋ชจ๋ ์ถ๊ฐํ๋ค. |
| void clear() | ๋ชจ๋ ๋ฐ์ดํฐ๋ฅผ ์ด๊ธฐํํ๋ค. |
| boolean contains(Object o) | ํ๋ผ๋ฏธํฐ๋ก ์ ๋ฌ๋ ๊ฐ์ฒด๋ฅผ ํฌํจํ๊ณ ์๋์ง ๊ฒ์ฌํ๋ค. |
| E get(int index) | ํน์ ์ธ๋ฑ์ค ์์น์ ์ ๋ค๋ฆญ ํ์ ์ ๋ฐ์ดํฐ๋ฅผ ๊ฐ์ ธ์จ๋ค. |
| int indexOF(Object o) | ํ๋ผ๋ฏธํฐ๋ก ์ ๋ฌ๋ ๊ฐ์ฒด์ ์ธ๋ฑ์ค๋ฅผ ๋ฆฌํดํ๋ค. |
| Iterator<E> iterator() | ์์ฐจ ๋ฐ์ดํฐ ์ฒ๋ฆฌ๋ฅผ ํ๋ ค๊ณ Iterator ๊ฐ์ฒด๋ฅผ ๊ฐ์ ธ์จ๋ค. |
| boolean remove(int index) | ํน์ ์ธ๋ฑ์ค ์์น์ ๋ฐ์ดํฐ๋ฅผ ์ญ์ ํ๋ค. |
| int size() | ArrayList ๊ฐ์ฒด์ ํฌํจ๋ ๋ฐ์ดํฐ์ ํฌ๊ธฐ๋ฅผ ๋ฆฌํดํ๋ค. |
ArrayList์ ๋์ ํ ๋น ๋ฐฉ์
ํฌ๊ธฐ๊ฐ ์ ํด์ ธ ์๋ ๋ฐฐ์ด๊ณผ ๋ฌ๋ฆฌ ArrayList๋ ๋ฐ์ดํฐ๊ฐ ์ถ๊ฐ๋ ๋ ์ด๋ป๊ฒ ์ฌ์ด์ฆ๊ฐ ๋์ ์ผ๋ก ๋์ด๋๋์ง ๋ด๋ถ ๋ฉ์๋๋ฅผ ํตํด์ ์์๋ณด๊ธฐ๋ก ํ๋ค.
/**
* Default initial capacity.
*/
private static final int DEFAULT_CAPACITY = 10;
/**
* Shared empty array instance used for empty instances.
*/
private static final Object[] EMPTY_ELEMENTDATA = {};
/**
* Shared empty array instance used for default sized empty instances. We
* distinguish this from EMPTY_ELEMENTDATA to know how much to inflate when
* first element is added.
*/
private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {};
/**
* The array buffer into which the elements of the ArrayList are stored.
* The capacity of the ArrayList is the length of this array buffer. Any
* empty ArrayList with elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA
* will be expanded to DEFAULT_CAPACITY when the first element is added.
*/
transient Object[] elementData;
๊ธฐ๋ณธ Capacity๊ฐ 10์ด๋ค. ArrayList๋ ์ค์ ๋ก ์ผ๋ฐ์ ์ธ Object ๋ฐฐ์ด์ ์ฌ์ฉํ๊ณ ์์์ ์ ์ ์๋ค.
๋น ArrayList๋ ์ฒซ ๋ฒ์งธ ์์๊ฐ ์ถ๊ฐ๋ ๋ ๊ธฐ๋ณธ Capacity๋ก ํฌ๊ธฐ๊ฐ ํ์ฅ๋๋ค๊ณ ํ๋ค.
/**
* Constructs an empty list with the specified initial capacity.
*
* @param initialCapacity the initial capacity of the list
* @throws IllegalArgumentException if the specified initial capacity
* is negative
*/
public ArrayList(int initialCapacity) {
if (initialCapacity > 0) {
this.elementData = new Object[initialCapacity];
} else if (initialCapacity == 0) {
this.elementData = EMPTY_ELEMENTDATA;
} else {
throw new IllegalArgumentException("Illegal Capacity: "+initialCapacity);
}
}
/**
* Constructs an empty list with an initial capacity of ten.
*/
public ArrayList() {
this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA;
}
ArrayList ์์ฑ ์ ์ด๊ธฐ ์ฉ๋์ ์ค ๊ฒฝ์ฐ์ ๋น ArrayList๋ก ์์ฑํ ๊ฒฝ์ฐ.
add() ๋ฉ์๋
/**
* This helper method split out from add(E) to keep method
* bytecode size under 35 (the -XX:MaxInlineSize default value),
* which helps when add(E) is called in a C1-compiled loop.
*/
private void add(E e, Object[] elementData, int s) {
if (s == elementData.length)
elementData = grow();
elementData[s] = e;
size = s + 1;
}
/**
* Appends the specified element to the end of this list.
*
* @param e element to be appended to this list
* @return {@code true} (as specified by {@link Collection#add})
*/
public boolean add(E e) {
modCount++;
add(e, elementData, size);
return true;
}
ํ์ฌ ArrayList ๋ด๋ถ์์ ๋์ํ๋ ๋ฐฐ์ด์ ํฌ๊ธฐ๊ฐ ๊ฐ์ ๋,
grow() ๋ผ๋ ๋ฉ์๋๋ก ํฌ๊ธฐ๋ฅผ ํ์ฅํด ์ค ๋ค ์ ๋ ฅ๋ฐ์ ์ธ๋ฑ์ค์ ์๋ก์ด ๊ฐ์ ์ถ๊ฐํ๊ณ ์๋ค.
๊ทธ๋ ๋ค๋ฉด grow()๋ ์ด๋ป๊ฒ ๋์ํ๊ณ ์์๊น. ๐
/**
* 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
* @throws OutOfMemoryError if minCapacity is less than zero
*/
private Object[] grow(int minCapacity) {
int oldCapacity = elementData.length;
if (oldCapacity > 0 || elementData != DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {
int newCapacity = ArraysSupport.newLength(oldCapacity,
minCapacity - oldCapacity, /* minimum growth */
oldCapacity >> 1 /* preferred growth */);
return elementData = Arrays.copyOf(elementData, newCapacity);
} else {
return elementData = new Object[Math.max(DEFAULT_CAPACITY, minCapacity)];
}
}
private Object[] grow() {
return grow(size + 1);
}
if (oldCapacity > 0 || elementData != DEFAULTCAPACITY_EMPTY_ELEMENTDATA)
๋จผ์ ํ์ฌ ArrayList๊ฐ ๋น์ด ์๋์ง ์๋์ง ํ์ธํ๋ค.
๋น์ด ์์ ๊ฒฝ์ฐ, else๋ก ๊ธฐ๋ณธ ์ฉ๋์ธ 10๊ณผ size + 1 ์ค ํฐ ๊ฐ์ผ๋ก ์ Object ๋ฐฐ์ด์ ์์ฑํ๋ค.
๊ทธ๋ ์ง ์์ ๊ฒฝ์ฐ, ์๋ก์ด capacity๋ก ํฌ๊ธฐ๋ฅผ ํ์ฅํด ์ค๋ค.
int newCapacity = ArraysSupport.newLength(oldCapacity, minCapacity - oldCapacity, oldCapacity >> 1);
oldCapacity : ๊ธฐ์กด ์ฉ๋
minCapacity - oldCapacity : (size + 1) - (elementData.length) = ์ผ๋ฐ์ ์ผ๋ก ์ต์ ์ฆ๊ฐ๊ฐ์ 1์ด ๋๋ค.
oldCapacity >> 1 : ๊ธฐ์กด ์ฉ๋ / 2 (์ฐ์ธก ์ฌํํธ ์ฐ์ฐ)
/**
* A soft maximum array length imposed by array growth computations.
* Some JVMs (such as HotSpot) have an implementation limit that will cause
*
* ...
*/
public static final int SOFT_MAX_ARRAY_LENGTH = Integer.MAX_VALUE - 8;
/**
* Computes a new array length given an array's current length, a minimum growth
* amount, and a preferred growth amount. The computation is done in an overflow-safe
* fashion.
*
* ...
*/
public static int newLength(int oldLength, int minGrowth, int prefGrowth) {
// preconditions not checked because of inlining
// assert oldLength >= 0
// assert minGrowth > 0
int prefLength = oldLength + Math.max(minGrowth, prefGrowth); // might overflow
if (0 < prefLength && prefLength <= SOFT_MAX_ARRAY_LENGTH) {
return prefLength;
} else {
// put code cold in a separate method
return hugeLength(oldLength, minGrowth);
}
}
์ด๋ง์ด๋งํ ์์ ์ฃผ์์ด๋ผ ์ค๊ฐ์ ์๋ตํ๋ค.
int prefLength = oldLength + Math.max(minGrowth, prefGrowth)
๊ธฐ์กด arrayList๊ฐ 10์ด๋ผ๊ณ ํ๋ค๋ฉด ์ผ๋ง๋ ๋๋ฆด์ง ์ฉ๋์ ์ ์ฅํ๋ prefLength์ 10๊ณผ minGrowth, prefGrowth ์ค ๋ ํฐ ๊ฐ์ธ 5๋ฅผ ๋ํด 15์ผ๋ก ์ค์ ํ๋ค. ๊ฒฐ๊ตญ ๊ธฐ์กด ํฌ๊ธฐ์์ 1.5๋ฐฐ๋ก ๋๋ ค ์๋ก์ด ํฌ๊ธฐ๋ฅผ ๊ฒฐ์ ํ๋ ๊ฒ์ด๋ค.
if (0 < prefLength && prefLength <= SOFT_MAX_ARRAY_LENGTH)
์๋ก์ด ํฌ๊ธฐ๊ฐ SOFT_MAX_ARRAY_LENGTH๋ฅผ ๋์ด๊ฐ์ง ์์ ๊ฒฝ์ฐ, ๊ทธ๋๋ก ๋๊ฒจ ์ฃผ์ง๋ง 0๋ณด๋ค ์๊ฑฐ๋ ์ต๋ ์ฉ๋ ๊ฐ์ ๋๋ ๊ฒฝ์ฐ๋ ์ด๋ป๊ฒ ๋ ๊น.
private static int hugeLength(int oldLength, int minGrowth) {
int minLength = oldLength + minGrowth;
if (minLength < 0) { // overflow
throw new OutOfMemoryError(
"Required array length " + oldLength + " + " + minGrowth + " is too large");
} else if (minLength <= SOFT_MAX_ARRAY_LENGTH) {
return SOFT_MAX_ARRAY_LENGTH;
} else {
return minLength;
}
}
int minLength = oldLength + minGrowth;
๊ธฐ์กด ํฌ๊ธฐ์ ์ต์ ์ฆ๊ฐ๊ฐ์ ๋ํด์ ์ค์ ํ ์ต์ ์ฉ๋์ด 0๋ณด๋ค ์์ ๊ฒฝ์ฐ OutOfMemoryError ๋ฐ์. SOFT_MAX_ARRAY_LENGTH ์ดํ์ธ ๊ฒฝ์ฐ์๋ ์ค์ ๋ int์ ์ต๋์น๋ฅผ ์ฉ๋์ผ๋ก ๋ถ์ฌํ๋ค.
๊ฒฐ๋ก ์ ์ผ๋ก
ArrayList๋ ์ ์์๋ฅผ ์ถ๊ฐํ๊ณ ์ ํ ๋, capacity๊ฐ ๊ธฐ์กด ๋ฐฐ์ด์ ํฌ๊ธฐ์ ๊ฐ์์ง๋ฉด ๊ธฐ์กด ์ฉ๋์ 1.5๋ฐฐ๋งํผ ์ฆ๊ฐ์ํค๊ณ ๊ทธ ํฌ๊ธฐ๊ฐ ๋์ด๋ ๋ฐฐ์ด์ ๊ธฐ์กด elementData๋ฅผ copyํ๋ค. ์ค์ ๋ก๋ ์ ์ ๋ฐฐ์ด์ ์ฌ์ฉํ์ง๋ง, ์์๊ฐ ์ถ๊ฐ๋ ๋๋ง๋ค ์ต์ ์ฆ๊ฐ๋์ ๊ณ์ฐํ์ฌ ํฌ๊ธฐ๋ฅผ ๋๋ฆฌ๋ ๋ฐฉ์์ด๋ผ๋ ๊ฒ์ ์ ์ ์์๋ค.
์ฐธ๊ณ
'๊ฐ๋ฐ > Etc.' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
| [WebSquare] ๊ทธ๋ฆฌ๋(Grid)์ ๋ฐ์ธ๋ฉ๋ ๋ฐ์ดํฐ ์ธ์ ๋ค๋ฅธ ๋ฐ์ดํฐ๋ฅผ ๋ฃ๊ณ ์ถ์ ๋ (0) | 2022.05.03 |
|---|