โ ์ข์ ๋์์ธ์ ๊ทธ ๋๋ฌธ์ ์๋ชจ๋๋ ๋น์ฉ๋ณด๋ค ๋น ๋ฅด๊ฒ ๊ฐ์น๊ฐ ์์ธ๋ค. โ
- Thomas C. Gale
๋ฏธ๊ตญ์ ์๋์ฐจ ๋์์ด๋

ArrayList ์๋ฃ๊ตฌ์กฐ
ArrayList ํน์ง์ผ๋ก ๋ค์๊ณผ ๊ฐ์ด ์์ฝ์ด ๊ฐ๋ฅํ๋ค.
- ์ฐ์์ ์ธ ๋ฐ์ดํฐ์ ๋ฆฌ์คํธ (๋ฐ์ดํฐ๋ ์ฐ์์ ์ผ๋ก ์ ์ฌ ๋์์ด์ผ ํ๋ฉฐ ์ค๊ฐ์ ๋น๊ณต๊ฐ์ด ์์ผ๋ฉด ์๋๋ค)
- ArrayList ํด๋์ค๋ ๋ด๋ถ์ ์ผ๋ก
Object[]๋ฐฐ์ด์ ์ด์ฉํ์ฌ ์์๋ฅผ ์ ์ฅ - ๋ฐฐ์ด์ ์ด์ฉํ๊ธฐ ๋๋ฌธ์ ์ธ๋ฑ์ค๋ฅผ ์ด์ฉํด ์์์ ๋น ๋ฅด๊ฒ ์ ๊ทผํ ์ ์๋ค.
- ํฌ๊ธฐ๊ฐ ๊ณ ์ ๋์ด์๋ ๋ฐฐ์ด๊ณผ ๋ฌ๋ฆฌ ๋ฐ์ดํฐ ์ ์ฌ๋์ ๋ฐ๋ผ ๊ฐ๋ณ์ ์ผ๋ก ๊ณต๊ฐ์ ๋๋ฆฌ๊ฑฐ๋ ์ค์ธ๋ค.
- ๊ทธ๋ฌ๋ ๋ฐฐ์ด ๊ณต๊ฐ์ด ๊ฝ ์ฐฐ๋ ๋ง๋ค ๋ฐฐ์ด์ copyํ๋ ๋ฐฉ์์ผ๋ก ๋๋ฆฌ๋ฏ๋ก ์ด ๊ณผ์ ์์ ์ง์ฐ์ด ๋ฐ์ํ๊ฒ ๋๋ค.
- ๋ฐ์ดํฐ๋ฅผ ๋ฆฌ์คํธ ์ค๊ฐ์ ์ฝ์ /์ญ์ ํ ๊ฒฝ์ฐ, ์ค๊ฐ์ ๋น ๊ณต๊ฐ์ด ์๊ธฐ์ง ์๋๋ก ์์๋ค์ ์์น๋ฅผ ์๋ค๋ก ์๋์ผ๋ก ์ด๋์ํค๊ธฐ ๋๋ฌธ์ ์ฝ์ /์ญ์ ๋์์ ๋๋ฆฌ๋ค.
- ๋ฐ๋ผ์ ์กฐํ๋ฅผ ๋ง์ด ํ๋ ๊ฒฝ์ฐ์ ์ฌ์ฉํ๋ ๊ฒ์ด ์ข๋ค
[JCF] ๐งฑ ArrayList ๊ตฌ์กฐ & ์ฌ์ฉ๋ฒ - ์๋ฒฝ ์ดํดํ๊ธฐ
ArrayList ์ปฌ๋ ์ ์๋ฐ์ ์ปฌ๋ ์ ํ๋ ์์ํฌ๋ฅผ ์ ํ๋ค๋ฉด, ๊ฐ์ฅ ๋จผ์ ๋ฐฐ์ฐ๋ ์ปฌ๋ ์ ์ด ArrayList ์ผ ๊ฒ์ด๋ฉฐ, ํ๋ก๊ทธ๋๋ฐ์ ์๋ฃ ๊ตฌ์กฐ์ค์ ๋ฐฐ์ด ๋ค์์ผ๋ก ๋ฐฐ์ฐ๋ ์๋ฃํ ์ผ ๊ฒ์ด๋ค. ์๋ฃ๊ตฌ์กฐ(Data Structure
inpa.tistory.com
ArrayList ์ค์ ๊ตฌํํ๊ธฐ (๊ธฐ๋ณธํธ)
java.util ํจํค์ง์ ArrayList๋ฅผ ๋ด๋ณด๋ฉด ๋ฉ์๋๊ฐ ๊ต์ฅํ ๋ง๋ค. ๋ฐ๋ผ์ ์ด๋ค์ ๋ชจ๋ ๊ตฌํํ๋ ๊ฒ๋ณด๋ค๋ ArrayList ์๋ฃํ์ ํน์ง์ ์ ์ ์๋ ๋ฉ์๋๋ง ๊ตฌํ์ ํจ์ผ๋ก์จ, ArrayList๊ฐ ์ฝ๋ ๋ด๋ถ์์ ์ด๋ป๊ฒ ๋์ํ๋์ง ์์ฃผ๋ก ๊ตฌํ์ ํด๋ณด๊ณ ์ ํ๋ค.
๊ทธ๋์ ์๋ฃ์ ํ๋ฆ์ ๊ทธ๋ฆผ์ผ๋ก๋ง ๋๋์ค์ผ๋ก ๋ณด๊ณ ๋์ด ๊ฐ์ํ ๋ฐ, ์ง์ ArrayList๋ฅผ ๊ตฌํํด๋ณด๋ฉด ์์ฐ์ค๋ฝ๊ฒ ์๋ฃ๊ตฌ์กฐ์ ๋ํด ์ฌ๋ ๊น์ ์ฒด๋์ด๋๋ฉฐ, ์์ผ๋ก์ ์๋ก์ด ์๋ฃ๊ตฌ์กฐ๋ฅผ ๋ง๋ค์ด์ ์จ์ผํ ๋ ์ฝ๋๋ฅผ ์ค๊ณํ๋ ๋ฐ๋ฐํ์ด ๋ ์๋ ์๊ธฐ ๋๋ฌธ์, ๊ทธ๋ฅ ๋ฉ์๋๋ฅผ ๊ฐ์ ธ๊ฐ ์ฐ๋ ๊ฒ์ ๋์ด ์ง์ ๊ตฌํ ๊ฒฝํ์ ํด๋ณด๋ ๊ฑธ ๊ถ์ฅํ๋ค.
List ์ธํฐํ์ด์ค ์ ์
์ค์ ๋ก ArrayList ํด๋์ค๋ List ์ธํฐํ์ด์ค๋ฅผ implements ํ์ฌ ๊ตฌํํ๊ธฐ ๋๋ฌธ์ ๋ณธ ํฌ์คํ
์์๋ ์ด์ ๋น์ทํ๊ฒ ์ธํฐํ์ด์ค๋ฅผ ๊ตฌํํ๊ณ ์ถ์ ๋ฉ์๋๋ฅผ ์ฌ์ ์ ํด๋ณด๋ฉฐ, ์ด๋ฅธ๋ฐ ํด๋ก ๋ฐ์ดํฐ ์คํธ๋ญ์ณ ์ฝ๋ฉ์ ํด๋ณด๋ ์๊ฐ์ ๊ฐ์ ธ๋ณผ๊ฒ์ด๋ค.
๋ค์์ ์ค์ List ์ธํฐํ์ด์ค์ ์ ์๋์ด ์๋ ์ถ์ ๋ฉ์๋๋ค ์ค ํต์ฌ์ ์ธ ๋ถ๋ถ๋ง ๋ฐ์ทํ์ฌ ๋๋ง์ ์ธํฐํ์ด์ค์ธ MyList๋ก ์ ๋ค๋ฆญ์ ์ด์ฉํ์ฌ ์ ์ํ์๋ค. ์ด MyList ์ธํฐํ์ด์ค๋ฅผ implements ํ์ฌ ๋๋ง์ MyArrayList๋ฅผ ๋ง๋ค์ด๋ณด์.
public interface MyList<T> {
boolean add(T value); // ์์๋ฅผ ์ถ๊ฐ
void add(int index, T value); // ์์๋ฅผ ํน์ ์์น์ ์ถ๊ฐ
boolean remove(Object value); // ์์๋ฅผ ์ญ์
T remove(int index); // ํน์ ์์น์ ์๋ ์์๋ฅผ ์ญ์
T get(int index); // ์์ ๊ฐ์ ธ์ค๊ธฐ
void set(int index, T value); // ํน์ ์์น์ ์๋ ์์๋ฅผ ์ ์์๋ก ๋์ฒด
boolean contains(Object value); // ํน์ ์์๊ฐ ๋ฆฌ์คํธ์ ์๋์ง ์ฌ๋ถ๋ฅผ ํ์ธ
int indexOf(Object value); // ํน์ ์์๊ฐ ๋ช ๋ฒ์งธ ์์น์ ์๋์ง๋ฅผ ๋ฐํ (์์ฐจ ๊ฒ์)
int lastIndexOf(Object o); // ํน์ ์์๊ฐ ๋ช ๋ฒ์งธ ์์น์ ์๋์ง๋ฅผ ๋ฐํ (์ญ์ ๊ฒ์)
int size(); // ์์์ ๊ฐ์๋ฅผ ๋ฐํ
boolean isEmpty(); // ์์๊ฐ ๋น์ด์๋์ง
public void clear(); // ์์๋ฅผ ๋ชจ๋ ์ญ์
}
public class MyArrayList<E> implements MyList<E> {
// ...
}
ํด๋์ค ํ๋ ์ ์ํ๊ธฐ
public class MyArrayList<E> implements MyList<E> {
private static final int DEFAULT_CAPACITY = 5; // ์์ฑ์๋ก ๋ฐฐ์ด์ด ์์ฑ๋ ๋ ๊ธฐ๋ณธ ์ฉ๋
private static final Object[] EMPTY_ELEMENTDATA = {}; // ๋น ๋ฐฐ์ด
private int size; // elementData ๋ฐฐ์ด์ ์ด ๊ฐ์(ํฌ๊ธฐ)๋ฅผ ๋ํ๋ด๋ ๋ณ์
Object[] elementData; // ์๋ฃ๋ฅผ ๋ด์ ๋ฐฐ์ด
// ...
}
- DEFAULT_CAPACITY : ๋ฐฐ์ด์ด ์์ฑ ๋ ๋์ ๋ํดํธ ํ ๋น ์ฉ๋
- EMPTY_ELEMENTDATA : ์๋ฌด ๊ฒ๋ ์๋ ๋น ๋ฐฐ์ด
- elementData : ์ค์ MyArrayList์ ๋ค์ด์ค๋ ๋ฐ์ดํฐ๋ค์ ๋ด๋ ๋ฐฐ์ด ์๋ฃ
- size : elementData ๋ฐฐ์ด์ ๋ด๊ธด ์์์ ์ด๊ฐ์(๋ฐฐ์ด ํฌ๊ธฐ)
ArrayList ํด๋์ค์ ๋ฐ์ดํฐ๋ค์ ์ ์ฅํ๊ธฐ ์ํด ๋ด๋ถ์ Object ๋ฐฐ์ด์ด ๊ตฌํ ๋์ด ์๋ค. ์ด ๋ด๋ถ ๋ฐฐ์ด์ ๊ฐ์ง๊ณ ๋ฉ์๋๋ก ์กฐ์ํ์ฌ ๋ฆฌ์คํธ ์๋ฃ๋ฅผ ์ด์ฉํ๋ ๊ฒ์ด๋ค.
๊ทธ๋ฐ๋ฐ ์ฌ๊ธฐ์ ๊ฐ์ฅ ์ค์ํ ๋ฉค๋ฒ๊ฐ ๋ฐ๋ก size ๋ณ์์ด๋ค. size๋ ๋ฐฐ์ด์ ํฌ๊ธฐ๋ฅผ ๋ํ๋ด๋ ๋ณ์์ธ๋ฐ, ์ด์ฐจํผ elementData.length๋ก ๊ณง๋ฐ๋ก ๋ฐฐ์ด์ ํฌ๊ธฐ๋ฅผ ์ป์์ ์์์๋ ๋ถ๊ตฌํ๊ณ ๋ฐ๋ก ๋ณ์๋ก ๋ถ๋ฆฌํ ์ด์ ๋, ์๋ฃ๋ฅผ ๋ด์ ๋ฐฐ์ด elementData์ ํฌ๊ธฐ๊ฐ MyArrayList ํด๋์ค์ ํฌ๊ธฐ๋ฅผ ๋๋ณํด์ฃผ์ง ๋ชปํ๊ธฐ ๋๋ฌธ์ด๋ค. ์๋ฅผ๋ค์ด ๋ฐ์ดํฐ๋ฅผ add ํ๋ค๊ณ ํ๋ฉด ๋ฐฐ์ด์ด ๊ฝ์ฐจ์๋์ง ๋น์ด์๋์ง ํ์ธ์ํ๊ณ ์ถ๊ฐํด์ผ ๋๋๋ฐ, ์ด๋ฌํ ๊ฒ์ฌ๋ฅผ size ๋ณ์์ ๊ฐ์ ๋น๊ต๋ฅผ ํตํด ์ฒ๋ฆฌํ๊ธฐ ๋๋ฌธ์ด๋ค. ๋ํ ์ ์ฌํ ์ธ๋ฑ์ค ์์น๊ฐ์ผ๋ก๋ ์ฐ์ฌ์ง๋ค.
๋ฆฌ์คํธ์ capacity์ size์ ์ฐจ์ด๋ฅผ ํผ๋ํ์ง ๋ง์์ผ ํ๋ค.
capacity๋ ๋ฐฐ์ด์ ์ ์ฒด ๊ณต๊ฐ ์ฉ๋์ ๋งํ๋ ๊ฒ์ด๊ณ , size๋ ๋ฐฐ์ด์ ๋ชจ๋ ์์์ ๊ฐฏ์(ํฌ๊ธฐ)๋ฅผ ๋ปํ๋ ๊ฐ๋ ์ด๋ค.
์์ฑ์ ๊ตฌํํ๊ธฐ
์๋ฐ์ ArrayList ์ฌ์ฉ๋ฒ์ ๋ณด๋ฉด ์ธ์คํด์คํ ํ ๋ ํ๋ผ๋ฏธํฐ๋ฅผ ์ฃผ๊ธฐ๋ ํ๊ณ ์ฃผ์ง ์๊ธฐ๋ ํ๋ค.
ํ๋ผ๋ฏธํฐ๋ฅผ ์ค ๊ฒฝ์ฐ ๋ฏธ๋ฆฌ ์ง์ ํ ์๋งํผ ๊ณต๊ฐ(capacity)์ ํ ๋นํ๋๋ฐ, ์ด๋ฅผ ๊ตฌํํ๊ธฐ ์ํด ์์ฑ์๋ฅผ overloading ์ฒ๋ฆฌํ๋ค. ๋ํ ์ฌ์ฉ์๊ฐ ํ๋ผ๋ฏธํฐ์ ์ณ์ง ์์ ๊ฐ์ ์ค์๋ ์์ผ๋ ์ด๋ฅผ ์บ์นํ์ฌ ์ ๋ถ๊ธฐ ์ฒ๋ฆฌํ์ฌ์ผ ํ๋ค.
MyArrayList<Object> list2 = new MyArrayList<>();
MyArrayList<Object> list1 = new MyArrayList<>(50);
MyArrayList<Object> list2 = new MyArrayList<>(0);
MyArrayList<Object> list3 = new MyArrayList<>(-50);
// ์์ฑ์ (์ด๊ธฐ ๊ณต๊ฐ ํ ๋น X)
public MyArrayList() {
this.elementData = new Object[DEFAULT_CAPACITY]; // ๋ํดํธ ์ฉ๋์ผ๋ก ์ด๊ธฐํ
this.size = 0;
}
// ์์ฑ์ (์ด๊ธฐ ๊ณต๊ฐ ํ ๋น O)
public MyArrayList(int capacity) {
// ํ๋ผ๋ฏธํฐ์ ๊ฐ์ด ์์์ผ ๊ฒฝ์ฐ ๊ทธ๋๋ก ์ฉ๋์ผ๋ก ๋ฐฐ์ด์ ์์ฑ
if (capacity > 0) {
this.elementData = new Object[capacity];
}
// ํ๋ผ๋ฏธํฐ์ ๊ฐ์ด 0์ผ ๊ฒฝ์ฐ ์ธ์๋ฅผ ์ฃผ์ง ์๊ณ ์ธ์คํด์คํ ํ ๊ฒ๊ณผ ๊ฐ์ผ๋ ๋ํดํธ ์ฉ๋์ผ๋ก ์ด๊ธฐํ
else if (capacity == 0) {
this.elementData = new Object[DEFAULT_CAPACITY];
}
// ํ๋ผ๋ฏธํฐ์ ๊ฐ์ ์์๋ก ์ค์ ํ ๊ฒฝ์ฐ ์์ธ๋ฅผ ๋ฐ์์ํค๋๋ก ์์ ํ๊ฒ ์ค๊ณ
else if (capacity < 0) {
throw new RuntimeException(new IllegalAccessException("๋ฆฌ์คํธ ์ฉ๋์ ์๋ชป ์ค์ ํ์์ต๋๋ค")); // Checked ์์ธ๋ฅผ Unchecked ์์ธ๋ก ๋ณํ
}
this.size = 0;
}
resize ๊ตฌํํ๊ธฐ
๋ฆฌ์คํธ์ ๋ฐฐ์ด์ ๊ฐ์ฅ ํฐ ์ฐจ์ด์ ์ ๋ฆฌ์คํธ๋ ๋์ ์ผ๋ก ํฌ๊ธฐ๋ฅผ ๋๋ ธ๋ค ์ค์๋ค ํ ์ ์๋ ๊ฒ์ด๋ค. (๊ฐ๋ณ ๋ฐฐ์ด)
๋ง์ผ ์ฉ๋(capaciy)๊ฐ ๊ฝ ์ฐจ์ ๋น๊ณต๊ฐ์ด ์๋๋ฐ ์๋ก์ด ๋ฐ์ดํฐ๊ฐ ๋ค์ด์ค๋ฉด ๋ฐฐ์ด์ ์ฉ๋์ ๋๋ฆด ํ์๊ฐ ์๋ค. ๋ฐ๋๋ก ๋ฐ์ดํฐ๋ฅผ ์ญ์ ํด์ ๋ค์ด์๋ ๋ฐ์ดํฐ ๊ฐฏ์์ ๋นํด ์ฉ๋์ด ๋๋ฌด ํฌ๋ค๋ฉด ๋ฐฐ์ด์ ์ฉ๋์ ์ค์ฌ ๋ฉ๋ชจ๋ฆฌ์ ์ผ๋ก ์ต์ ํ๋ฅผ ๋ ธ๋ฆด ์๋ ์๋ค.
resize() ๋ฉ์๋๋ ๋ฆฌ์คํธ์ ์์๊ฐ ์ถ๊ฐ, ์ญ์ ๋ฑ์ ๋์์ด ๋ ๋ ๊ธฐ๋ณธ์ ์ผ๋ก ํธ์ถ๋๋ค. ๊ทธ๋ฆฌ๊ณ ๋ฐฐ์ด์ ํฌ๊ธฐ(size)์ ๋ฐฐ์ด์ ์ฉ๋(capaciy)์ ๋น๊ตํ์ฌ, ํฌ๊ฑฐ๋ ์์ ๊ฒฝ์ฐ ์ด๋ฅผ ๊ฐ์งํด์ ๋ฆฌ์ฌ์ด์ง์ ์ฒ๋ฆฌํ์ฌ ๋ฉ๋ชจ๋ฆฌ ์ต์ ํ๋ฅผ ๋ ธ๋ฆฐ๋ค๊ณ ๋ณด๋ฉด ๋๋ค.
๋ค์๊ณผ ๊ฐ์ด ๋ฐฐ์ด์ ๋ฐ์ดํฐ๊ฐ ์ถ๊ฐ/์ญ์ ๋ ๋๋ง๋ค ์คํ๋๋ resize() ๋ด๋ถ์ฉ ๋ฉ์๋ ๊ตฌํํ๊ณ , size์ capacity๋ฅผ ๋น๊ตํ๋ ์ด 3๊ฐ์ง์ ๋ถ๊ธฐ๋ฅผ ๊ตฌํํด์ค๋ค.
// ํด๋์ค ๋ด๋ถ์์๋ง ์คํ๋๋ ๋ฉ์๋์ด๋ private
private void resize() {
int element_capacity = elementData.length; // ํ์ฌ ๋ฐฐ์ด์ ํฌ๊ธฐ๋ฅผ ์ป์
// ์ฉ๋์ด ๊ฝ์ฐฌ ๊ฒฝ์ฐ
if() ...
// ์ฉ๋์ ๋นํด ๋ฐ์ดํฐ ์์ด ์ ์ ๊ฒฝ์ฐ
if() ...
// ๋ค์ด์๋ ๋ฐ์ดํฐ๊ฐ ํ๋๋ ์์ ๊ฒฝ์ฐ (๋น ๋ฐฐ์ด ์ผ๊ฒฝ์ฐ)
if() ...
}
1. ์ฉ๋์ด ๊ฝ์ฐฌ ๊ฒฝ์ฐ
์๋ ์ฝ๋์์ ์ฉ๋์ 2๋ฐฐ๋ก ์ค์ ํ๋ ์ด์ ๋ ๋๋ํ๊ฒ ๊ณต๊ฐ์ ์ ์งํ๊ธฐ ์ํด์์ด๋ค. ์๋ํ๋ฉด resize ๋ฉ์๋๊ฐ ์์ฃผ ํธ์ถ๋์ด ๋ฐฐ์ด์ ๋ณต์ฌํ์ฌ ์๋ก ๋ง๋๋ ํ์๊ฐ ๋น๋ฒํ ์ผ์ด๋๋ค๋ฉด ์ฑ๋ฅ์ ๋ง์ด๋์ค๊ฐ ๋ ์ ์๊ธฐ ๋๋ฌธ์ด๋ค. ๋น ๊ณต๊ฐ์ ์๋์ผ๋ก null๋ก ์ฑ์์ง๊ธฐ ๋๋ฌธ์ ๋ฌธ์ ๋ ์๋ค.
๋ค๋ง ์๋ฃ๊ตฌ์กฐ ์๊ณ ๋ฆฌ์ฆ์ ๋ฐ๋ผ ํ์ฅ ๊ธฐ์ค์ด ๋ค๋ฅผ์ ์๋ค๋ ์ ์ ์ ์ํ์.
// ์ฉ๋์ด ๊ฝ์ฐฌ ๊ฒฝ์ฐ
if (element_capacity == size) {
int new_capacity = element_capacity * 2; // ๋๋ํ๊ฒ ๊ณต๊ฐ์ ์ ์งํ๊ธฐ ์ํด ํ์ฌ ์ฉ๋์ ๋๋ฐฐ๋ก ์ค์
elementData = Arrays.copyOf(elementData, new_capacity); // ๋ณต์ฌํ ๋ฐฐ์ด์ new_capacity ์ฉ๋ ๋งํผ ์ค์ ํ๊ณ elementData ์์๋ค์ ์ ์ฒด ๋ณต์ฌํด์ ๋ฃ๊ณ ๋ฐํ (๋น๊ณต๊ฐ์ null)
return;
}
2. ์ฉ๋์ ๋นํด ๋ฐ์ดํฐ ์์ด ์ ์ ๊ฒฝ์ฐ
์ ์ ํ ๊ณต๊ฐ์ ์ ์งํ๋ค ๋๋ฌด ๋ฐฐ์ด ์์๊ฐ ๊ณต๊ฐ์ ๋นํด ์ ๊ฒ ๋ค์ด์์ ๊ฒฝ์ฐ ์ต์ ํ๋ฅผ ์ํด ๋ฆฌ์ฌ์ด์ง ํ๋ ์์ ์ด๋ค.
ํฌ๊ธฐ ๊ณ์ฐ ๊ธฐ์ค์ ํ์ฌ ๋ฐฐ์ด ์์ ๊ฐฏ์(size)๊ฐ ํ์ฌ ๋ฐฐ์ด ์ฉ๋(capacity)์ ์ ๋ฐ ๋ณด๋ค ์์ ๊ฒฝ์ฐ๋ก ์ ํ์๋ค. ๊ทธ๋ฆฌ๊ณ ๋ฐฐ์ด์ ๋ณต์ฌํ ๋ ์ถ์ํ ๋ฐฐ์ด์ ์ฉ๋์ ์ ํ ๋ Math.max() ๋ฉ์๋๋ฅผ ์ด์ฉํ์๋๋ฐ, ์์์ ๋ฆฌ์คํธ์ ๊ธฐ๋ณธ ํ ๋น ์ฉ๋์ ์ ํ์์ผ๋, ์ด์ ๋ํ ์์น์ ๋ฐ๋ฅด๊ธฐ ์ํด ์ ๋ฐ์ผ๋ก ์ค์ธ ์ฉ๋๋ณด๋ค ๊ธฐ๋ณธ ์ฉ๋์ด ๋ ํด ๊ฒฝ์ฐ ๊ธฐ๋ณธ ์ฉ๋์ผ๋ก ์ค์ ํ๊ธฐ ์ํด์๋ค.
// ์ฉ๋์ ๋นํด ๋ฐ์ดํฐ ์์ด ์ ์ ๊ฒฝ์ฐ
if ((element_capacity / 2) > size) {
int half_capacity = element_capacity / 2;
elementData = Arrays.copyOf(elementData, Math.max(half_capacity, DEFAULT_CAPACITY)); // half_capacity ์ ๋ํดํธ ์ฉ๋ ์ค ํฐ๊ฑธ ๋ณต์ฌ
return;
}
3. ๋ค์ด์๋ ๋ฐ์ดํฐ๊ฐ ํ๋๋ ์์ ๊ฒฝ์ฐ
๋ง์ผ clear() ์ ๊ฐ์ ๋ฐ์ดํฐ ์ ์ฒด ์ญ์ ๋ฅผ ์คํํ ๊ฒฝ์ฐ, ๋์ด์ ๋ค์ด์๋ ๋ฐฐ์ด ์์๊ฐ ์์ผ๋ ์ด๋ ๋ํดํธ ์ฉ๋์ผ๋ก ๋ฐฐ์ด์ ์ด๊ธฐํ ํ๋ค. ์ด๋ ๋น๋ฐฐ์ด์ธ ๊ฒ์ ํ์ธํ๊ธฐ ์ํด Arrays.equals() ๋ฉ์๋๋ฅผ ์ด์ฉํด ๋น๊ต๋ฅผ ํ๋ค.
// ๋ค์ด์๋ ๋ฐ์ดํฐ๊ฐ ํ๋๋ ์์ ๊ฒฝ์ฐ (๋น ๋ฐฐ์ด ์ผ๊ฒฝ์ฐ)
if (Arrays.equals(elementData, EMPTY_ELEMENTDATA)) {
elementData = new Object[DEFAULT_CAPACITY]; // ๊ธฐ๋ณธ ์ฉ๋์ผ๋ก ์ด๊ธฐํ
return;
}
add ๊ตฌํํ๊ธฐ
์๋ฃ๋ฅผ ์ถ๊ฐํ๋ ๋ฉ์๋๋ add(E value) ๋ฉ์๋์ add(int index, E value) ๊ฐ ์๋ค.
- add(E value) : ๊ฐ์ฅ ๋ ๋ถ๋ถ์ ์ถ๊ฐ
- add(int index, E value) : ํน์ ์์น์ ์ถ๊ฐ
add(E value)
๊ฐ์ฅ ๋ง์ง๋ง ๋ถ๋ถ์ ๋ฐ์ดํฐ๋ฅผ ๋ฃ์ผ๋ฉด ๋๋ ๊ตฌํ ์์ฒด๋ ์ด๋ ต์ง ์๋ค.
@Override
public boolean add(Object value) {
resize(); // ํ์ฌ ๋ฐฐ์ด์ด ๊ฝ ์ฐจ์๋ ์ํ์ด๋ฉด ๋ฆฌ์ฌ์ด์ง
elementData[size] = value; // size๊ฐ ์์์ ๊ฐฏ์์ด๊ณ , ๋ฐฐ์ด์ ์ธ๋ฑ์ค๋ 0๋ถํฐ ์์ํ๋ ๊ฒฐ๊ตญ ์ถ๊ฐํ ์ ์๋ ๋ง์ง๋ง ์์น๋ฅผ ๊ฐ๋ฆฌํค๊ฒ ๋๋ค.
size++; // ์์๊ฐ ์ถ๊ฐ๋์์ผ๋, ๋ฐฐ์ด ํฌ๊ธฐ๋ฅผ ๋ํ๋ด๋ size๋ ์ฌ๋ฆฐ๋ค.
return true;
}
์ด๋ ์ ์ํด์ ๋ณผ ์ ์ ๋ฐฐ์ด์ ์ธ๋ฑ์ค๋ก size ๋ณ์๋ฅผ ์ฌ์ฉํ๋ค๋ ์ ์ธ๋ฐ, size ๊ฐ ์์ฒด๊ฐ ๋ฐฐ์ด ์์ ์๋ ์์์ ๊ฐฏ์์ด๊ณ , ๋ฐฐ์ด์ index๋ 0๋ถํฐ ์์ํ๋, ๊ฒฐ๊ตญ์ size ๊ฐ์ด ์์ ๋ง์ง๋ง์ ๋ค์ ์์น๋ฅผ ๊ฐ๋ฆฌํค๋ ๊ฒ๊ณผ ๋ค๋ฆ์ด ์๋ค. (๋น์ด์๋ ๊ณต๊ฐ์ค ์ฒซ๋ฒ์งธ ์์น)
๋ฐ์ดํฐ๋ฅผ ๋ฃ์ผ๋ฉด ๋ง์ง๋ง์ผ๋ก size ๋ณ์๋ ๋ฐ๋์ ์ ๋ฐ์ดํธ ํด์ฃผ๋ ๊ฒ์ ์์ง๋ง์. ์ด๋ฅผ ๊ทธ๋ฆผ์ผ๋ก ๋ํ๋ด์๋ฉด ์๋ ๋ก์ง๋๋ก ํ๋ฌ๊ฐ๊ฒ ๋๋ค.

add(int index, E value)
์ค๊ฐ์ ๋ฐ์ดํฐ๋ฅผ ์ฝ์ ํ๋ ๊ฒ์ ๊ธฐ๋ณธ ์ฝ์ ๋ณด๋ค ํ์ธํด์ผํ ์ ์ฐจ๊ฐ ์ฝ๊ฐ ์๋ค. ์๋ํ๋ฉด ๋ฆฌ์คํธ๋ ๋ฐ์ดํฐ๊ฐ ์ฐ์๋์ด ์ ์ฅ๋์ด ์๋ ๋ฐฐ์ด์ธ๋ฐ ์ค๊ฐ์ ๋น๊ณต๊ฐ์ด ์๋ ์ฑ๋ก ์์๊ฐ ๋ค์ด์๊ฑฐ๋ ์์๊ฐ ๋ค์ด๋ก๋ฉด ์๋๊ธฐ ๋๋ฌธ์ด๋ค.

- ๋งค๊ฐ๋ณ์๋ก ๋ฐ์์จ ์ธ๋ฑ์ค ๋ฒ์๊ฐ ์์์ ๊ฐ์ ์ณ์ง ์์ ๊ฐ์ด ์ฌ ๊ฒฝ์ฐ (index < 0)
- ๋งค๊ฐ๋ณ์๋ก ๋ฐ์์จ ์ธ๋ฑ์ค ๋ฒ์๊ฐ ํ์ฌ ๋ฐฐ์ด ์ฉ๋(capacity)๋ณด๋ค ์ด๊ณผ ๋๊ฑฐ๋, ์ค๊ฐ์ ๋น๊ณต๊ฐ์ด ๋จ์์ฑ๋ก ๋ ๋ถ๋ถ์ ์ถ๊ฐ ํ๋์ง (index > size)
@Override
public void add(int index, Object value) {
// ์ธ๋ฑ์ค๊ฐ ์์์ด๊ฑฐ๋, ๋ฐฐ์ด ํฌ๊ธฐ(size)๋ฅผ ๋ฒ์ด๋ ๊ฒฝ์ฐ ์์ธ ๋ฐ์ (๋ฆฌ์คํธ๋ ๋ฐ์ดํฐ๊ฐ ์ฐ์๋์ด์ผํจ)
if (index < 0 || index > size) {
throw new IndexOutOfBoundsException();
}
// ...
}
๋ง์ผ ์์ ์ค๊ฐ์ ๋ฐ์ดํฐ๋ฅผ ์ฝ์ ํ๋ค๊ณ ํ๋ฉด, ๊ธฐ์กด ์์๋ค์ ๋ํด ํ์นธ์ฉ ์์ผ๋ก ์ด๋ํ๋ ์ ์ฐจ๋ฅผ ๊ตฌํํ์ฌ์ผ ํ๋ค. ๊ทธ๋์ผ ๋น๊ณต๊ฐ์ด ์ค๊ฐ์ ์๊ธฐ๊ฒ ๋๊ณ ๊ทธ๊ณณ์ ๊ฐ์ ์ฝ์ ํ ์ ์๊ธฐ ๋๋ฌธ์ด๋ค.
์ฝ๋๋ฅผ ๋ณด๊ธฐ ์ ์ ๋ฐ์ดํฐ๊ฐ ์ค๊ฐ์ ์ถ๊ฐ๋๋ ๊ณผ์ ์ ๊ทธ๋ฆฐ ๊ทธ๋ฆผ์ ๋จผ์ ๋ณด์ฌ ์ค๊ฐ ์ฝ์ ๊ณผ์ ์ ์ดํดํด๋ณด์.

@Override
public void add(int index, Object value) {
// ์ธ๋ฑ์ค๊ฐ ์์์ด๊ฑฐ๋, ๋ฐฐ์ด ํฌ๊ธฐ(size)๋ฅผ ๋ฒ์ด๋ ๊ฒฝ์ฐ ์์ธ ๋ฐ์ (๋ฆฌ์คํธ๋ ๋ฐ์ดํฐ๊ฐ ์ฐ์๋์ด์ผํจ)
if (index < 0 || index > size) {
throw new IndexOutOfBoundsException();
}
// ์ธ๋ฑ์ค๊ฐ ๋ง์ง๋ง ์์น์ผ ๊ฒฝ์ฐ
if (index == size) {
add(value); // ๊ทธ๋ฅ ์ถ๊ฐ
}
// ์ธ๋ฑ์ค๊ฐ ์ค๊ฐ ์์น๋ฅผ ๊ฐ๋ฆฌํฌ ๊ฒฝ์ฐ
else {
resize(); // ํ์ฌ ๋ฐฐ์ด์ด ๊ฝ ์ฐจ์๋ ์ํ์ด๋ฉด ๋ฆฌ์ฌ์ด์ง
// ๋ฃจํ๋ณ์์ ๋ฐฐ์ด ํฌ๊ธฐ๋ฅผ ๋ฃ๊ณ , index ์์น ๊น์ง ์ํํด์ ์์๋ค ํ ์นธ ์ฉ ๋ค๋ก ๋ฐ์ด ๋น ๊ณต๊ฐ ๋ง๋ค๊ธฐ
for (int i = size; i > index; i--) {
elementData[i] = elementData[i - 1];
}
elementData[index] = value; // index ์์น์ ์์ ํ ๋น
size++;
}
}
indexOf ๊ตฌํํ๊ธฐ
๋ฐฐ์ด์์ ํด๋น ๊ฐ์ด ๋ค์ด์๋ ์ธ๋ฑ์ค ์์น๋ฅผ ์ป๋ ๋ฉ์๋๋ ๋ค์๊ณผ ๊ฐ๋ค.
- indexOf(Object value) : ์์ฐจ๋๋ก ๊ฒ์ํด์ ์์น ๋ฐํ
- LastindexOf(Object value) : ๊ฑฐ๊พธ๋ก ๊ฒ์ํด์ ์์น ๋ฐํ
๋ง์ผ ์ฐพ๊ณ ์ ํ๋ ๊ฐ์ด ๋ฐฐ์ด์ ์ค๋ณต์ผ๋ก ์ฌ๋ฌ๊ฐ ๋ค์ด์์ผ๋ฉด, ๊ฐ์ฅ ๋จผ์ ๊ฒ์๋๋ ์์์ ์์น๋ฅผ ๋ฐํํ๋ค. ๊ทธ๋ฆฌ๊ณ ๋ง์ผ ์ฐพ๊ณ ์ ํ๋ ๊ฐ์ด ์์ ๊ฒฝ์ฐ -1 ์ ๋ฐํํ๋๋ก ์ค์ ํ๋ค.
์ ์ํด์ผ ํ ์ ์ ์ปฌ๋ ์
์๋ ๋ฌด์กฐ๊ฑด ๊ฐ์ฒด๋ง ๋ค์ด์ฌ ์ ์๊ธฐ ๋๋ฌธ์ ์์๋ผ๋ฆฌ ๋น๊ตํ ๋๋ ๋๋ฑ ์ฐ์ฐ์(==)๊ฐ ์๋๋ผ ๋ฐ๋์ equals() ๋ฉ์๋๋ก ๋น๊ตํด์ผ ํ๋ค. ๋๋ฑ ์ฐ์ฐ์๋ฅผ ์ฐ๋ฉด ๊ฐ์ฒด์ ์ฃผ์๊ฐ์ ๋น๊ตํ๋ ๊ฒ์ด๊ธฐ ๋๋ฌธ์ด๋ค.
indexOf(Object value)
ArrayList๋ ์ ํํ ๊ฐ๊ณผ ๋๋ถ์ด null๋ ์ ์ฅํ ์ ์๋ ์๋ฃ๊ตฌ์กฐ์ด๋ค. ๊ทธ๋ฐ๋ฐ null ๋น๊ต ๊ฐ์ ๊ฒฝ์ฐ ๋๋ฑ ์ฐ์ฌ์๋ก ํด์ผํ๊ธฐ ๋๋ฌธ์ ์ด์ฉ์ ์์ด ๋งค๊ฐ๋ณ์๊ฐ null์ผ ๊ฒฝ์ฐ๊ฐ ์ค์ง ๊ฐ์ธ ๊ฒฝ์ฐ๋ฅผ ๋๋์ด์ผ ํ๋ค.
@Override
public int indexOf(Object value) {
// ๋งค๊ฐ๋ณ์๊ฐ null ์ผ๊ฒฝ์ฐ (null ๋น๊ต๋ ๋๋ฑ์ฐ์ฐ์๋ก ํํ๊ธฐ ๋๋ฌธ์ ๋น๊ต ๋ก์ง์ ๋ถ๋ฆฌ)
if (value == null) {
for (int i = 0; i < size; i++) {
if (elementData[i] == null) {
return i; // ์ธ๋ฑ์ค ๋ฐํ
}
}
}
// ๋งค๊ฐ๋ณ์๊ฐ ์ค์ง์ ์ธ ๊ฐ์ผ ๊ฒฝ์ฐ
else {
for (int i = 0; i < size; i++) {
if (elementData[i].equals(value)) {
return i; // ์ธ๋ฑ์ค ๋ฐํ
}
}
}
return -1; // ์ฐพ์ ๊ฐ์ด ์์ ๊ฒฝ์ฐ
}
LastindexOf(Object value)
์์ฐจ ๊ฒ์์ด 0 ์์ size ๋ฏธ๋ง๊น์ง ๊ฒ์ํ ๊ฒ์ด๋, ์ญ์ ๊ฒ์์ ๊ทธ ๋ฐ๋์ธ, size - 1 ์๋ถํฐ 0 ๊น์ง ์ํํ๋ฉฐ ๊ฒ์ํ๋ฉด ์ญ์ ๋ก์ง์ ๊ตฌํํ ์ ์๋ค.
@Override
public int lastIndexOf(Object value) {
if (value == null) {
for (int i = size - 1; i >= 0; i--) {
if (elementData[i] == null) {
return i; // ์ธ๋ฑ์ค ๋ฐํ
}
}
} else {
for (int i = size - 1; i >= 0; i--) {
if (elementData[i].equals(value)) {
return i; // ์ธ๋ฑ์ค ๋ฐํ
}
}
}
return -1; // ์ฐพ์ ๊ฐ์ด ์์ ๊ฒฝ์ฐ
}
remove ๊ตฌํํ๊ธฐ
์์ ์ ๊ฑฐ ๋ฉ์๋์ ๊ฒฝ์ฐ ํฌ๊ฒ 2๊ฐ์ง๋ก ๋๋๋ค.
- remove(int index) : ํน์ index์ ์์๋ฅผ ์ญ์
- remove(Object value) : ํน์ ์์๋ฅผ ์ญ์
remove(int index)
์ด๋ ต๊ฒ ์๊ฐํ ํ์์์ด ์์์ ๋ค๋ฃจ์๋ add(int index, E value) ๋ฐฉ์์ ๊ฑฐ๊พธ๋ก ๊ตฌํํ๋ฉด ๋๋ค.

@Override
@SuppressWarnings("unchecked")
public E remove(int index) {
// 1. ์ธ๋ฑ์ค๊ฐ ์์์ด๊ฑฐ๋, size ๋ณด๋ค ๊ฐ๊ฑฐ๋ ํด๊ฒฝ์ฐ (size์ ๊ฐ๋ค๋ ๋ง์ ์์ ์์น๊ฐ ๋น๊ณต๊ฐ ์ด๋ผ๋ ๋ง)
if (index < 0 || index >= size) {
throw new IndexOutOfBoundsException();
}
// 2. ๋ฐํํ ๊ฐ ๋ฐฑ์
E element = (E) elementData[index];
// 3. ์์ ์ ๊ฑฐ (๋ช
์์ ์ผ๋ก ์์๋ฅผ null๋ก ์ฒ๋ฆฌํด์ฃผ์ด์ผ GC๊ฐ ์๊ฑฐํด๊ฐ)
elementData[index] = null;
// 4. ๋ฐฐ์ด ์์ ์ด๋ (์ญ์ ํ ์์์ ๋ค์ ์๋ ๋ชจ๋ ์์๋ค์ ํ ์นธ์ฉ ๋น๊ฒจ์ด)
for (int i = index; i < size - 1; i++) {
elementData[i] = elementData[i + 1];
elementData[i + 1] = null;
}
// 5. ์์๋ฅผ ์ ๊ฑฐํ์ผ๋ size๋ ๊ฐ์
size--;
// 6. ํ์ฌ ๋ฐฐ์ด์ด capacity๊ฐ ๋๋ฌด ๋จ์๋๋ ์ํ์ด๋ฉด ๋ฆฌ์ฌ์ด์ง
resize();
// 7. ๋ฐฑ์
ํ ์ญ์ ๋ ์์๋ฅผ ๋ฐํ
return element;
}
- ๋จผ์ ์ธ๋ฑ์ค๊ฐ ์ณ์ง์์ ๊ฐ์ด๊ฑฐ๋ ๋ฐฐ์ด ํฌ๊ธฐ(size)๋ณด๋ค ํฐ ๊ฒฝ์ฐ๋ ์์ธ๋ฅผ ๋ฐ์์ํค๋๋ก ํ๋ค.
- ๊ธฐ๋ณธ์ ์ผ๋ก
remove()๋ฉ์๋ ์คํ์ ๋ฐํ๊ฐ์ ์ญ์ ๋ ์์๋ฅผ ๋ณด๋ด๊ธฐ ๋๋ฌธ์, ๋ฆฌ์คํธ์์ ์์๋ฅผ ์ญ์ ํ๊ธฐ ์ ์ ๋ณ์์ ๋ฐฑ์ ์ ํด์ผํ๋ค.
์ด๋ ๊ฐ์ ธ์ค๊ฒ๋๋ ์์๊ฐ Object ํ์ ์ด๋ผ ์ ๋ค๋ฆญ E ํ์ ์ผ๋ก ํ๋ณํํด์ค์ผ ํ๋๋ฐ, ํ๋ณํ ํ๋ ๊ณผ์ ์์ ๊ฒฝ๊ณ ์ฐฝ์ด ๋จ๊ฒ ๋๋ค. ์ ๋ค๋ฆญ ์์ฒด๊ฐ ํ์ธ๋์ง ์์ ๋ชจํธํ ํ์ ์ด๋ผ ๊ทธ๋ ๋ค. ๋ฐ๋ผ์ ์ด์ฐจํผ ๋ฆฌ์คํธ์์ ์ ๋ค๋ฆญ ํ์ ์ผ๋ก๋ง ์์๋ฅผ ๋ค๋ฃจ๊ธฐ ๋๋ฌธ์ ํ ์์ ์ฑ์ด ํ๋ณด๋๋ฏ๋ก@SuppressWarnings("unchecked")์ด๋ ธํ ์ด์ ์ ๋ถ์ธ๋ค. ํ๋ง๋๋ก ClassCastException์ด ๋จ์ง ์์ผ๋ ์ด ๊ฒฝ๊ณ ๋ค์ ๋ฌด์ํ๊ฒ ๋ค๋ ์๋ฏธ์ด๋ค. - ๊ทธ๋ฆฌ๊ณ ํด๋น ์์น์ null์ ๋์ ํจ์ผ๋ก์จ, ๊ธฐ์กด์ ์์์ ๊ฐ์ฒด๊ฐ ๊ฐ๋น์ง ๊ฐ์ด ๋์ด GC๊ฐ ์ฒ๋ฆฌํ๋๋ก ํด์ค๋ค.
- for๋ฌธ์ ๋๋ ค์
add()๋ฉ์๋์ ๊ฐ์ด ์ด๋ฒ์ ๋ฐ๋๋ก ์ํํ์ฌ ๋ค์ ์๋ ์์๋ค์ ํ์นธ์ฉ ์์ผ๋ก ๋น๊ฒจ์จ๋ค.
์ด๋ ์ ์ฌ๋์ด์๋ ๋ง์ง๋ง ์์์ ์์น๋ size - 1 ์ธ ์ ์ ์ ์ํด์ผ ๋๋ค. ์๋ํ๋ฉด ์์ผ๋ก ๋น๊ฒจ์ค๋ ๊ณผ์ ์์ ๋ ์์ ์ด์ ๊น์ง๋ง ์ํํ๋ฉด ๋๊ธฐ ๋๋ฌธ์ด๋ค. - ์์๋ฅผ ์ญ์ ํ์ผ๋ฉด size ๋ณ์๊ฐ์ ์ค์ฌ์ฃผ๊ณ
- ํน์๋๋ฅผ ์ํด ๋ฆฌ์ฌ์ด์ง๋ ํด์ค๋ค.
- ๋ง์ง๋ง์ผ๋ก ๋ฐฑ์ ํ ์ญ์ ๋ ์์๋ฅผ ๋ฐํํ๋ค.
@SuppressWarnings("unchecked")์ด๋ ธํ ์ด์ ์ ํ ๋ณํ์ ์์ธ ๊ฐ๋ฅ์ฑ์ด ์์ ํ์คํ ๊ฒฝ์ฐ์๋ง ์จ์ฃผ๋ ๊ฒ์ด ์ข๋ค. ๊ทธ๋ ์ง ์์ผ๋ฉด ์ค์ํ ๊ฒฝ๊ณ ๋ฉ์ธ์ง๋ฅผ ๋์น ์๋ ์๊ธฐ ๋๋ฌธ์ด๋ค.
remove(Object value)
remove(Object value) ๋ฉ์๋๋ ์ธ๋ฑ์ค๋ก ์์น๋ฅผ ์ฐพ์์ ๊ทธ ์์๋ฅผ ์ญ์ ํ๋ ๊ฒ์ด ์๋, ์์ ์์ฒด๋ฅผ ๋ค์ ธ์ ์ฐพ์ ์ญ์ ํ๋ ๋์์ด๋ค. ์ด๋ ์ค๋ณต๋ ๊ฐ์ ๊ฐ์ ์์๊ฐ ์์ ๊ฒฝ์ฐ indexOf() ๋ฉ์๋์ ๊ฐ์ด ๊ฐ์ฅ ๋จผ์ ๋งค์นญ๋๋ ์์๋ง ์ญ์ ๋๋ค.
remove(Object value) ๋ฉ์๋๋ฅผ ์์ ๊ฐ์ด for๋ฌธ์ผ๋ก ์ผ์ผํ ๊ตฌํํด๋ ๋์ง๋ง, ์ด๋ฒ์ ๋จผ์ ๋ง๋ค์๋ remove(int index) ๋ฉ์๋์ indexOf() ๋ฉ์๋๋ฅผ ์ฌํ์ฉํ์ฌ ์กฐํฉํ์ฌ ๋ณด๋ค ๊ฐ๋จํ๊ฒ ๊ตฌํํ ์ ์๋ค.
@Override
public boolean remove(Object value) {
// 1. ๋จผ์ ํด๋น ์์๊ฐ ๋ช๋ฒ์งธ ์์น์ ์กด์ฌํ๋์ง ์ธ๋ฑ์ค๋ฅผ ์ป์ด์จ๋ค.
int idx = indexOf(value);
// 2. ๋ง์ฝ ๊ฐ์ด -1์ด๋ฉด ์ญ์ ํ๊ณ ์ ํ๋ ๊ฐ์ด ์๋ ๊ฒ์ด๋ ๊ทธ๋๋ก ๋ฉ์๋๋ฅผ ์ข
๋ฃํ๋ค.
if(idx == -1) return false;
// 3. ์ธ๋ฑ์ค๋ฅผ ์ฐพ์์ผ๋ฉด ๊ทธ๋๋ก remove() ๋ฉ์๋๋ก ๋๊ฒจ ์ญ์ ํ๋ค. (remove() ์์ ์์ ์ญ์ ๋ฐ size๊ฐ์ ๋ฆฌ์ฌ์ด์ง ์ฒ๋ฆฌ)
remove(idx);
return true;
}
get / set ๊ตฌํํ๊ธฐ
add์ remove ๊น์ง ๊ตฌํํ ๋ ์๋ถ๋ค์ด๋ผ๋ฉด ์ด ๋ถ๋ถ์ ์ฝ๊ฒ ๊ตฌํ์ด ๊ฐ๋ฅํ ๊ฒ์ด๋ค. ์์ง๋ง์์ผ ํ ์ ์ get๊ณผ set ๋์ ์ญ์ ์ธ๋ฑ์ค๋ฅผ ํ๋ผ๋ฏธํฐ๋ก ๋๊ฒจ ๋ฆฌ์คํธ ์์๋ฅผ ๊ฐ์ ธ์ค๊ธฐ ๋๋ฌธ์ ์ ์ ์น ์์ ์ธ๋ฑ์ค ๋ฒ์์ ๋ํ ์์ธ ์ฒ๋ฆฌ๋ฅผ ํด์ฃผ์ด์ผ ๋๋ค.
@SuppressWarnings("unchecked")
@Override
public E get(int index) {
if (index < 0 || index >= size) {
throw new IndexOutOfBoundsException();
}
return (E) elementData[index]; // ์์๊ฐ ๋ฐํ (ํ๋ณํ ํ์)
}
@Override
public void set(int index, Object value) {
if (index < 0 || index >= size) {
throw new IndexOutOfBoundsException();
}
elementData[index] = value; // ์์ ๊ต์ฒด
}
์ฝ๋๋ฅผ ๋ณด๋ฉด, remove ๋ฉ์๋์์๋ get๊ณผ set ๋ฉ์๋์์ ๋์ผํ ๋ฒ์ ์ฒดํฌ if๋ฌธ ์ฝ๋๊ฐ ๋ฐ๋ณต๋์ด ์ฝ๋ ์ค๋ณต์ด ๋ฐ์ํ๋๋ฐ, ์ด๋ฅผ ๋ฐ๋กrangeCheck()์ด๋ผ๋ private ๋ฉ์๋๋ก ๋นผ์ ๊ฐ์ฒด์ ์์ง๋๋ฅผ ๋์ด๋ ๋ฆฌํฉํ ๋ง๋ ๊ฐ๋ฅํ๋ค.
๊ธฐํ ์์ ๊ตฌํํ๊ธฐ
size ๊ตฌํ
MyArrayList ํด๋์ค์์๋ size ๋ณ์๊ฐ private ์ ๊ทผ์ ํ์๋ฅผ ๊ฐ๊ธฐ ๋๋ฌธ์ ๋ง์ผ ์ธ๋ถ์์ ์ฐธ์กฐ๊ฐ ํ์ํ๋ค๋ฉด ๋ฉ์๋๋ฅผ ํตํด ๋ฐํํ๋ ์์ผ๋ก ์ฒ๋ฆฌํด์ผ ํ๋ค. ๋ง์ผ size ๋ณ์๊ฐ pubilc์ด๋ผ๋ฉด ์ธ๋ถ์์ ๊ณ ์์ ์ผ๋ก size๊ฐ์ ๋ฐ๊ฟ๋ฒ๋ฆฌ๋ฉด MyArrayList ๋์ ์์ฒด๊ฐ ์ด์ํด๋ฒ๋ฆด์ ์๊ธฐ ๋๋ฌธ์ด๋ค.
@Override
public int size() {
return size;
}
isEmpty ๊ตฌํ
๋ฆฌ์คํธ๊ฐ ๋น์ด์๋์ง ์๋์ง ํ์ธํ๋ ค๋ฉด ์์ฃผ ๊ฐ๋จํ๊ฒ ์์์ ๊ฐฏ์์ธ size ๋ณ์๊ฐ์ด 0์ธ์ง๋ง ํ์ธํ๋ฉด ๋๋ค.
@Override
public boolean isEmpty() {
return size == 0;
}
clear ๊ตฌํ
๋ชจ๋ ์์๋ค์ ์ง์ฐ๊ธฐ ์ํด ๋ฐ๋ณต๋ฌธ์ผ๋ก ๋ฐฐ์ด ์ ์ฒด๋ฅผ ์ํํ์ฌ ๊ฐ ์์ ๊ณต๊ฐ์ null์ ๋์ ํ๋ ์์ผ๋ก ๊ตฌ์ฑํ ์๋ ์๊ฒ ์ง๋ง, ์๊ฐ์ ํ๊ธฐํ์ฌ ๊ทธ๋ฅ ๋น ๋ฐฐ์ด์ ๋ฃ์ด์ฃผ๋ฉด ํจ์ฌ ๊ฐ๋จํ๊ฒ ๊ตฌ์ฑํ ์ ์๋ค.
@Override
public void clear() {
elementData = new Object[DEFAULT_CAPACITY]; // ๊ธฐ๋ณธ ์ฉ๋์ผ๋ก ์ด๊ธฐํ
size = 0; // ๋ชจ๋ ์์๋ฅผ ์ง์ ์ผ๋ size๋ ์ด๊ธฐํ
}
contains ๊ตฌํ
indexOf() ๋ฉ์๋๋ ์ฌ์ฉ์๊ฐ ์ฐพ๊ณ ์ ํ๋ ์์(value)์ ์์น๋ฅผ ๋ฐํํ๋ ๋ฉ์๋์๋ค๋ฉด, contains() ๋ฉ์๋๋ ์ฌ์ฉ์๊ฐ ์ฐพ๊ณ ์ ํ๋ ์์๊ฐ ์กด์ฌ ํ๋์ง ์ํ๋์ง๋ฅผ ๋ฐํํ๋ ๋ฉ์๋๋ค. ์ฐพ๊ณ ์ ํ๋ ์์๊ฐ ์กด์ฌํ๋ค๋ฉด true๋ฅผ, ์กด์ฌํ์ง ์๋๋ค๋ฉด false๋ฅผ ๋ฐํํ๋ค. ์ด ์ญ์ ๊ธฐ์กด์ indexOf() ๋ฉ์๋๋ฅผ ์ฌํ์ฉํ์ฌ ๋งค์ฐ ๊ฐ๋จํ๊ฒ ๊ตฌํํ ์ ์๋ค.
@Override
public boolean contains(Object value) {
// ์ธ๋ฑ์ค๊ฐ์ด 0๋ณด๋ค ํฌ๋ฉด ๊ณง ์์์ ์์น๋ก์ ์์๊ฐ ์กด์ฌํ๋ค๋ ๊ฒ์ด๊ณ , 0๋ณด๋ค ์์ผ๋ฉด -1 ๋ก์ ์์๊ฐ ์กด์ฌํ์ง ์๋๋ค๋ ๊ฒ์ด๋ค.
return indexOf(value) >= 0 ? true : false;
}
toString ๊ตฌํ
ArrayList ์ปฌ๋ ์ ๊ฐ์ฒด๋ฅผ ๊ทธ๋๋ก print ํ์๋ ๋ณ๋ค๋ฅธ ์์ ์์ด ๋ฐฐ์ด๋ก ์ด์๊ฒ ์ถ๋ ฅ๋๋ ๊ฒ์ ๋ด์์ ๊ฒ์ด๋ค.
ArrayList<Integer> list = new ArrayList<>();
list.add(1);
list.add(2);
list.add(3);
list.add(4);
System.out.println(list); // [1, 2, 3, 4]
์๋ํ๋ฉด ArrayList ํด๋์ค์๋ Object ํด๋์ค์ toString() ๋ฉ์๋๋ฅผ ์ฌ์ ์ํด์ ์ด์๊ฒ ์ถ๋ ฅํ๋๋ก ๋ง๋ค์๊ธฐ ๋๋ฌธ์ด๋ค. ์ฐ๋ฆฌ์ MyArrayList ์ปฌ๋ ์
๋ ๋ค์๊ณผ ๊ฐ์ด ๊ฐ๋จํ๊ฒ ์ฌ์ ์ํ๋ฉด ์์ ๊ฐ์ด ๋ฐฐ์ด์ ์ด์๊ฒ ์ถ๋ ฅํ ์ ์๋ค.
@Override
public String toString() {
return Arrays.toString(elementData);
}
ArrayList ์ค์ ๊ตฌํํ๊ธฐ (์ฌํํธ)
์ง๊ธ๊น์ง ArrayList์ ์ฃผ์ ๋ฉ์๋๋ค์ ์ง์ ๊ตฌํํด ๋ณด์๋ค. ์ด์ ๋๋ฉด ๊ธฐ๋ณธ์ ์ธ ArrayList ์๋ฃ๊ตฌ์กฐ์ ๋์ ์๋ฆฌ๋ฅผ ์ต๋ํ๋๋ฐ ์์ด ์ถฉ๋ถํ ๊ฒ์ด๋ค.
๊ทธ๋๋ ๋ฐฐ์ด์ ์กฐ์ํ๋ ์ข ๋ ์ฌํ์ ์ธ ๊ธฐ๋ฅ๊ณผ ๋๋ถ์ด Collection์ ์ดํฐ๋ ์ดํฐ(Iterator) ๊ฐ์ฒด์ ๋์ ์๋ฆฌ๋ ์์๋ณด๊ณ ์ถ๋ค๋ฉด ํ๋ฒ ๋์ ํด๋ณด๋ ๊ฒ๋ ๋์์ง ์๋ค.
ListIterator ๊ตฌํํ๊ธฐ
๋ฆฌ์คํธ๋ฅผ ์ํํ ๋ for๋ฌธ์ผ๋ก๋ ์ถฉ๋ถํ์ง๋ง ์ดํฐ๋ ์ดํฐ ํจํด ๊ธฐ๋ฒ์ ์ฌ์ฉํด ์ํํ๋ ๋ฐฉ๋ฒ๋ ์๋ ๊ฑธ ๋ฐฐ์ ์ ๊ฒ์ด๋ค.
ListIterator ์ธํฐํ์ด์ค๋ Iterator ์ธํฐํ์ด์ค๋ฅผ ์์๋ฐ์ ์ฌ๋ฌ ๊ธฐ๋ฅ์ ์ถ๊ฐํ ๋ฆฌ์คํธ์ฉ ์ดํฐ๋ ์ดํฐ ์ธํฐํ์ด์ค์ด๋ค. Iterator ์ธํฐํ์ด์ค๋ ์ปฌ๋ ์ ์ ์์์ ์ ๊ทผํ ๋ ํ ๋ฐฉํฅ์ผ๋ก๋ง ์ด๋ํ ์ ์์ง๋ง, ListIterator ์ธํฐํ์ด์ค๋ ์๋ฐฉํฅ์ผ๋ก ์ด๋์ด ๊ฐ๋ฅํ๋ฉฐ, ์์์ ์ถ๊ฐ, ์ญ์ ๊ธฐ๋ฅ๋ ์ง์ํ๋ค.
// ListIterator ๊ฐ์ฒด๋ฅผ listIterator() ๋ฉ์๋๋ฅผ ํตํด ๋ฐ์
ListIterator<Integer> iter = lnkList.listIterator();
// ๋ง์ผ ๋ค์ ์์๊ฐ ์๋ค๋ฉด ๋ฐ๋ณต
while (iter.hasNext()) {
System.out.println(iter.next()); // ์์๋ฅผ ์ถ๋ ฅํ๊ณ ๋ฐ๋ณต ์์น๋ฅผ ๋ค๋ก ์ด๋
}
// ๋ง์ผ ์ด์ ์์๊ฐ ์๋ค๋ฉด ๋ฐ๋ณต
while (iter.hasPrevious()) {
System.out.println(iter.previous()); // ์์๋ฅผ ์ถ๋ ฅํ๊ณ ๋ฐ๋ณต ์์น๋ฅผ ์์ผ๋ก ์ด๋
}
๊ทธ๋ฐ๋ฐ ์ดํฐ๋ ์ดํฐ๋ผ๊ณ ํด์ ๋ฌด์จ ๋๋จํ ๊ตฌ์กฐ์ธ์ค ์๊ฒ ์ง๋ง, ์ฌ์ค ๊ทธ๋ฅ ๋ด๋ถ ํด๋์ค์ด๋ฉฐ, ๋ฉ์๋๋ก ๋ถํฐ ๋ด๋ถ ์ธ์คํด์ค ๊ฐ์ฒด๋ฅผ ์์ฑํ์ฌ ๋ฆฌํด๋ฐ์ ๊ฐ์ฒด์ ๋ฉ์๋๋ฅผ ์คํํ๋ ๊ฒ์ผ ๋ฟ์ด๋ค. (์ ๋ง ๋ณ๊ฑฐ์๋ค)

ListIterator ๋ด๋ถ ํด๋์ค ์์ฑ
์ฐ์ ์์ ๋ฆฌ์คํธ ์ดํฐ๋ ์ดํฐ ์ฌ์ฉ ์ฝ๋๋ฅผ ๋ณด๋ฉด ๋ณ์์ ํ์
์ ListIterator<E> ์ธํฐํ์ด์ค ํ์
์ผ๋ก ๋ฐ๋ ๊ฑธ ๋ณผ ์์๋ค. ๋คํ์ฑ์ ์ด์ฉํด DIP ์์น์ ๋ฐ๋ฅธ ์์ด๋ค. ์ด์ ๋๊ฐ์ด ์ฐ๋ฆฌ๋ MyListIterator ์ธํฐํ์ด์ค๋ฅผ ๋จผ์ ๋ง๋ค์ด์ค๋ค.
public interface MyListIterator<T> {
T next();
boolean hasNext();
T previos();
boolean hasPrevios();
void add(Object element);
void remove();
}
๊ทธ๋ฆฌ๊ณ ListIterator ๋ด๋ถ ํด๋์ค๋ฅผ MyArrayList ํด๋์ค์์ ์ค์ฒฉ์ผ๋ก ์ ์ธํด์ฃผ๊ณ , ์์์ ๋ง๋ MyListIterator ์ธํฐํ์ด์ค๋ฅผ implements ํด์ค๋ค.
ListIterator ๋ด๋ถ ํด๋์ค๋ static ์ด ์๋ ์ผ๋ฐ inner class๋ก ์ ์ธํด์ฃผ๋๋ฐ, ์๋ํ๋ฉด ์ธ๋ถ ํด๋์ค MyArrayList์ ๋ด๋ถ ๋ฐฐ์ด์ ์ฐธ์กฐํ์ฌ ์ฌ์ฉํด์ผ๋๊ธฐ ๋๋ฌธ์ด๋ค.
public class MyArrayList<E> implements MyList<E> {
private static final int DEFAULT_CAPACITY = 5; // ์์ฑ์๋ก ๋ฐฐ์ด์ด ์์ฑ๋ ๋ ๊ธฐ๋ณธ ์ฉ๋
private static final Object[] EMPTY_ELEMENTDATA = {}; // ๋น ๋ฐฐ์ด
// ...
// ...
// ...
// DIP ์์น์ ์ํด ์ธํฐํ์ด์ค๋ฅผ ์์
class ListIterator implements MyListIterator<E> {
private int nextIndex = 0; // ์ปค์ ์์น
public E next() {
}
public boolean hasNext() {
}
public E previos() {
}
public boolean hasPrevios() {
}
public void add(Object element) {
}
public void remove() {
}
}
// ๋ด๋ถ ํด๋์ค ListIterator ๊ฐ์ฒด๋ฅผ ๋ง๋ค์ด ๋ฐํ
public ListIterator listIterator() {
return new ListIterator();
}
}
ListIterator ๋ด๋ถ ํด๋์ค๋ฅผ ๋ง๋ค์์ผ๋ฉด, ๋ด๋ถ ํด๋์ค๋ฅผ ์ธ์คํด์คํ ํ์ฌ ๋ฐํํด์ฃผ๋ listIterator() ๋ฉ์๋๋ ์ ์ธํด์ค๋ค. ๊ทธ๋ฌ๋ฉด ํด๋ผ์ด์ธํธ์์ ๋ฆฌ์คํธ ์ดํฐ๋ ์ดํฐ ๊ฐ์ฒด๋ฅผ ๋ฐํ๋ฐ์ ์ค๋น๊ฐ ๋๋๊ฒ ๋๋ค.
์ด๋ ๊ฒ ์ดํฐ๋ ์ดํฐ ์์ฒด๋ ๊ฐ๋จํ์ง๋ง, ์ฌ๊ธฐ์ ์ ์ฌํ ์ดํด๋ด์ผ ํ ๋ฉค๋ฒ๋ nextIndex ๋ณ์์ด๋ค. nextIndex ๋ณ์๋ ์ดํฐ๋ ์ดํฐ๊ฐ ํ์ฌ ๋ฐฐ์ด ์ด๋ ์์น๋ฅผ ๊ฐ๋ฆฌํค๊ณ ์๋์ง์ ๋ํ ์ดํฐ๋ ์ดํฐ ์ ์ฉ ์ปค์ ์ญํ ์ ํ๋ค.
์ด ๋ณ์๋ฅผ ์ด์ฉํด์ size ์ฒ๋ผ ๋ฆฌ์คํธ๋ฅผ ์ฐจ๋ก๋ก ์ํ๋ฅผ ๋ ๊ฒ์ด๋ฉฐ ๋ํ ๊ฐ์ ๋ฐํํ๊ธฐ๋ ํ ๊ฒ์ด๋ค. ๋ค๋ง ๋ฐํ๊ณผ ๋์์ ์ปค์๊ฐ ์ด๋ํ๊ธฐ ๋๋ฌธ์, ๋๋๋ฅผ ์กฐ๊ธ ํ์ ํด์ผ ํ๋ค.
hasNext ๊ตฌํ
while ๋ฌธ์ ๋ฐ๋ณต ์์๋ก ์ฌ์ฉ๋๋ ๋ฉค๋ฒ์ด๋ฉฐ, ์ํํ ์์๊ฐ ๋จ์์๋์ง ์ฒดํฌํ๋ ๋ฉ์๋์ด๋ค. ๋ฐฐ์ด ์์์ ๊ฐฏ์๋ฅผ ๋ํ๋ด๋ size ๋ณ์๊ฐ๊ณผ nextIndex๋ฅผ ๋น๊ตํ์ฌ ๊ตฌํํ๋ฉด ๋๋ค.
@Override
public boolean hasNext() {
// nextIndex๊ฐ ๋ฐฐ์ด ์ฌ์ด์ฆ๋ณด๋ค ์๋ค๋ ๊ฒ์ ์ํํ ์์๊ฐ ๋จ์์๋ค๋ ๋ป
return nextIndex < size();
}
next ๊ตฌํ
๋ฆฌ์คํธ ์์๋ฅผ ๋ฐํํ๊ณ ์ดํฐ๋ ์ดํฐ ์ปค์๋ฅผ ๋ค์์ผ๋ก ์ฎ๊ธฐ๋ ๋ฉ์๋์ด๋ค. ์ฆ๊ฐ์ฐ์ฐ์๋ฅผ ์ด์ฉํด ๋ฐํ ๋ฐ ์ธ๋ฑ์ค ์ฆ๊ฐ ๋ก์ง์ ํ ์ค๋ก ์ฒ๋ฆฌํ์๋ค. ๊ทธ๋ฆฌ๊ณ @SuppressWarnings("unchecked") ์ด๋
ธํ
์ด์
์ ํตํด ์ ๋ค๋ฆญ ํ์
ํ๋ณํ์ด ์์ ํ๋ค๊ณ ์ปดํ์ผ๋ก ์๋ ค์ค๋ค.
@Override
@SuppressWarnings("unchecked")
public E next() {
// ๋ฐฐ์ด ์์๋ฅผ ๋ฐํํ๊ณ nextIndex 1 ์ฆ๊ฐ
return (E) elementData[nextIndex++]; // elementData[nextIndex] ์ nextIndex++ ๋ฅผ ํ์ค๋ก ํฉ์น ๊ฒ์ด๋ค.
}
hasPrevious ๊ตฌํ
hasNext() ๋ฉ์๋์ ๋ฐ๋๋ฒ์ ์ด๋ค. ์ฃผ์ํ ์ ์ ๋ฐฐ์ด์ ์ธ๋ฑ์ค๊ฐ 0๋ถํฐ ์์ํ๋ค๊ณ ํด์, 0๋ณด๋ค ํฌ๊ฑฐ๋ ๊ฐ์ผ๋ฉด ์๋๋ค. ์๋ํ๋ฉด ๋ฐ๋ก ๋ค์์ ๊ตฌํํ preivous ๋ฉ์๋์์์ ๋ก์ง ๋๋ฌธ์ ๊ทธ๋ ๋ค.
@Override
public boolean hasPrevios() {
// nextIndex๊ฐ 0๋ณด๋ค ํฌ๋ฉด ์ด์ ์์๊ฐ ๋จ์์๋ค๋ ๋ป
return nextIndex > 0; // ์ธ๋ฑ์ค๊ฐ 0๋ถํฐ ๋ผ๊ณ ํด์ >= 0 ์ด ์๋๋ค. previous ๋ฉ์๋์์ --nextIndex๋ฅผ ํ๊ธฐ ๋๋ฌธ์ 0๋ณด๋ค ๋ฌด์กฐ๊ฑด ์ปค์ผ๋๋ค.
}
previous ๊ตฌํ
next ๋ฉ์๋์ ๋ก์ง์ ๋ฐ๋๋ก ๊ตฌํํ๋ฉด ๋์ง๋ง, ์ฆ๊ฐ ์ฐ์ฐ์์ ์์น๊ฐ ๋ค๋ฅด๋ค๋ ์ ์ ์ ์ํ์.
์ฆ, next ๋ก์ง์ ๊ฐ์ ๋ฐํํ๊ณ ์ปค์๋ฅผ ๋ค๋ก ์ด๋ํ๋ ๊ฒ์ด๋ผ๋ฉด, previous ๋ก์ง์ ์ปค์๋ฅผ ์์ผ๋ก ๋จผ์ ์ด๋์ํ๊ณ ๋์์ผ ๊ฐ์ ๋ฐํํ๋ค๋ ์์์ ์ฐจ์ด์ ์ด ์กด์ฌํ๋ค. ์๋ํ๋ฉด nextIndex ์ปค์๋ ๋ฐํํ ์์ ๋ค์ ์์น๋ฅผ ๊ฐ๋ฆฌํค๋ ํน์ํ ์ธ๋ฑ์ค ์ด๊ธฐ ๋๋ฌธ์ด๋ค.
@Override
@SuppressWarnings("unchecked")
public E previos() {
// ๋ฐฐ์ด ์์๋ฅผ ๋ฐํํ๊ณ nextIndex 1 ๊ฐ์
return (E) elementData[--nextIndex]; // ์ด๋ ์ฆ๊ฐ์ฐ์ฐ์๋ฅผ ์์๋ค ๋ถ์ฌ์ฃผ์ด์ผ ํ๋ค
}
add / remove ๊ตฌํ
์ค์ ๋ฆฌ์คํธ ์ดํฐ๋ ์ดํฐ ๋ฉ์๋ ๋ชฉ๋ก์ ๋ณด๋ฉด ์์๋ฅผ ์ถ๊ฐํ๊ณ ์ ๊ฑฐํ๋ ๊ธฐ๋ฅ๋ ๋ฐ๋ก ์ง์ํ๋ค. ๋น๋ก ์ ํ์ ๋ฉ์๋์ด๊ธด ํ์ง๋ง, ๋ฆฌ์คํธ๋ฅผ ์ํํ๋ฉด์ ํน์ฌ๋ ์์ ํ ๊ฒ์ด ์๊ธด๋ค๋ฉด ์ฌ์ฉํ๋ผ๊ณ ์๋ ๊ฒ์ด๋ค.
์ฒ์๋ถํฐ ์์ผ๋ก ๊ตฌํํ ํ์์๊ณ ์ด๋ฏธ add์ remove ๊ธฐ๋ฅ์ MyArrayList ํด๋์ค์์ ๊ตฌํ์ ํ์์ผ๋ ์ฌํ์ฉ ํ๋ฉด ๋๋ค. ์ด๋ ๋ด๋ถ ํด๋์ค์์ ์ธ๋ถ ํด๋์ค์ ๋ฉ์๋๋ฅผ ๋ถ๋ฌ์ค๊ธฐ ์ํด์๋ ์ ๊ทํ๋ this ๋ผ๋ ๊ธฐ๋ฒ์ ์ฌ์ฉํ์ฌ์ผ ํ๋ค. ์์ ๊ด๊ณ๋ผ๋ฉด super๋ฅผ ์ฐ๋ฉด ๋๊ฒ ์ง๋ง, ๋ด๋ถ-์ธ๋ถ ๊ด๊ณ๋ ์์์ด ์๋๊ธฐ ๋๋ฌธ์ด๋ค.
์ด๋ remove ๋ฉ์๋์์ nextIndex ์ฒ๋ฆฌ๊ฐ ์ฝ๊ฐ ๋ณต์กํ๋ฐ, nextIndex ์์ฒด๊ฐ ๋ฐํํ ๋ค์ ์์๋ฅผ ๊ฐ๋ฆฌํค๋ ๊ฒ์ด๋ previos ๋ฉ์๋ ์ฒ๋ผ ๋ฐ๋์ 1์ ๊ฐ์ ์์ผ์ผ ํ๋ค.
@Override
public void add(Object element) {
// ์ดํฐ๋ ์ดํฐ ์ปค์ ์์น์ ์์๋ฅผ ์ถ๊ฐ
MyArrayList.this.add(nextIndex, element);
}
@Override
public void remove() {
// ์ดํฐ๋ ์ดํฐ ์ปค์ ์์น์ ์ ์์๋ฅผ ์ ๊ฑฐ (next ๋ฉ์๋ ์์ฒด๊ฐ ํ์ฌ ์์น์ ์์๋ฅผ ๋ฐํํ๊ณ ์ปค์๋ฅผ 1 ๋ํ๋๊น)
MyArrayList.this.remove(nextIndex-1);
// ์์๊ฐ ๋ฐฐ์ด์์ ์ ๊ฑฐ ๋์์ผ๋ size๊ฐ ์ค์ด๋ ๋ค. ๊ทธ๋ฆฌ๊ณ ์ปค์๋ ์์ผ๋ก ๋น๊ฒจ์ผ ํ๋ค. (์์๊ฐ ์ ๊ฑฐ๋์์ผ๋๊น)
nextIndex--;
}
clone ๊ตฌํํ๊ธฐ
๊ฐ์ฒด๋ฅผ ๋จ์ํ = ๋์
์ฐ์ฐ์๋ก ํ ๋นํ๋ฉด, ์์๊ฐ ๋ณต์ฌ ๋๋๊ฒ ์๋๋ผ ๊ฐ์ฒด ์ฃผ์๊ฐ ๋ณต์ฌ๋๊ฒ ๋๋ค. ์๋ํ๋ฉด ๊ธฐ๋ณธ์ ์ผ๋ก ์ปฌ๋ ์
๋ค์ ๊ฐ๋จํ ์ ์, ์ค์๋ผ๋ ๋ชจ๋ Wrapper ๊ฐ์ฒด๋ก ์ ์ฅํ๊ธฐ ๋๋ฌธ์, ์ฌ์ค ๋ฐฐ์ด์ ์ ์ฌ๋์ด์๋ ์์๋ค์ ๊ฐ ์์ฒด๊ฐ ์ ์ฌ๋์ด์๋๊ฒ ์๋๋ผ ์ฃผ์ ๋ฒ์ง๊ฐ์ด ์ ์ฌ ๋์ด์๊ธฐ ๋๋ฌธ์ด๋ค.

๋ฐ๋ผ์ ์ปฌ๋ ์ ์์ฒด๋ ๊ฐ์ฒด์ด๊ณ ์์ ๋ค์ด์๋ ์์๋ ๊ฐ์ฒด์ด๊ธฐ ๋๋ฌธ์ ์ด๋ค์ ์๋ฒฝํ clone ํ๊ธฐ ์ํด์๋ ํ๋ํ๋ ์ํํ์ฌ ์ผ์ผํ ์์๋ค์ ๋ณต์ฌํ๋ ์ฝ๊ฐ ๋ฅ(deep)ํ ์์ ์ด ํ์ํ๋ค.
๊ฐ์ฒด ๋ณต์ฌ๋ฅผ ๊ตฌํํ๊ธฐ ์ํด์, ์๋ฐ์ Object ํด๋์ค์ ์๋ clone() ๋ฉ์๋๋ฅผ ์ฌ์ ์ํ์ฌ ๊ตฌํํ ๊ฒ์ด๋ค. ์ด๋ถ๋ถ์ ์ด๋ ค์ด ํํธ๋ผ ์ ์ ์ง์์ด ํ์ํ๋ค. Object ํด๋์ค์ clone ๋ฉ์๋ ์ฌ์ฉ๋ฒ์ ๋ค์ ํฌ์คํ
์ ์ฐธ๊ณ ํ๊ธธ ๋ฐ๋๋ค.
- clone ๋ฉ์๋๋ฅผ ์ฌ์ ์ํ๊ณ , CloneNotSupportedException๋ฅผ throws ํ๋ค. (clone์ ๊ธฐ๋ณธ ์คํ)
- MyArrayList ์์ฒด๋ฅผ ๋ณต์ฌํ์ฌ ๋ณ์์ ์ ์ฅํ๋ค.
- ์ด๋ ๋ณต์ฌ ๊ณผ์ ์์ ๋ฐฐ์ด ๋ด์ฉ๋ฌผ์ด ๊ทธ๋๋ก ๋ณต์ฌ๋๋๋ฐ, ์ด๋ ๋ณต์ฌ๋๋ ์์๋ค์ ๊ฐ์ฒด ๋ฐ์ดํฐ๊ฐ ์๋๋ผ ์ฃผ์ ๋ฒ์ง๋ค์ด ๋ณต์ฌ๋์ด ๋ฒ๋ฆฐ๋ค.
- ๋ฐ๋ผ์ ๋ณต์ฌํ MyArrayList์ Object ๋ฐฐ์ด์ ์ฌ์์ฑํ๊ณ ,
- Arrays.copyOf ๋ฉ์๋๋ฅผ ์ด์ฉํด ์์์ ๊ฐ์ฒด๋ค์ ๊น์ ๋ณต์ฌ๋ฅผ ํํ๋๋ก ํ๋ค.
@Override
public Object clone() throws CloneNotSupportedException {
// 1. MyArrayList ์์ฒด๋ฅผ ๋ณต์ฌํ์ฌ ๋ณ์์ ์ ์ฅ
MyArrayList<?> cloneList = (MyArrayList<?>) super.clone();
// 2. ๋ณต์ฌํ MyArrayList์ Object ๋ฐฐ์ด์ ์ฌ์ด์ฆ๋ฅผ ๋ฏธ๋ฆฌ ์ง์ ํ์ฌ ์ฌ์์ฑ
cloneList.elementData = new Object[size];
// 3. ๋ฆฌ์คํธ์ ์ ์ฅํ๋ ๋ฐ์ดํฐ๋ ๊ฐ์ฒด(reference ํ์
)์ด๊ธฐ ๋๋ฌธ์ ๋ฐ๋์ ์์ ์์๋ค๋ ๋ฐ๋ก๋ฐ๋ก ๋ณต์ฌ๋ฅผ ํด์ค์ผ ํจ
cloneList.elementData = Arrays.copyOf(elementData, size); // ์๋ก์ด ๋ฐฐ์ด = Arrays.copyof(์๋ณธ ๋ฐฐ์ด, ์๋ณธ ๋ฐฐ์ด์์ ๋ณต์ฌํ๊ณ ์ถ์ ์์๋ค์ ๋ฒ์);
return cloneList;
}
์ ๋ง๋ก ๊ฐ์ฒด์ ๊น์ ๋ณต์ฌ๊ฐ ์ด๋ฃจ์ด์ก๋์ง ํ์ธํ๊ธฐ ์ํด ๋ฉ์ธ ํจ์์ ๋ค์๊ณผ ๊ฐ์ด ๋ฆฌ์คํธ๋ฅผ ์ง์ ๋ง๋ค์ด์ ํ ์คํธ๋ฅผ ํด๋ณด์.
public static void main(String[] args) throws Exception {
MyArrayList<Integer> l = new MyArrayList<>();
l.add(new Integer(1));
l.add(new Integer(2));
l.add(new Integer(3));
// ๋ฆฌ์คํธ ๋ณต์ฌ
MyArrayList<Integer> l2 = (MyArrayList<Integer>) l.clone();
// ๋ฆฌ์คํธ๊ฐ ์ ๋ณต์ฌ๋์๋์ง ๋ฆฌ์คํธ ์ฃผ์๊ฐ์ด ๋ค๋ฅธ์ง ๋น๊ต
System.out.println(l.hashCode());
System.out.println(l2.hashCode());
// ๋ฆฌ์คํธ์ ์์๋ค์ด ์๋ก ๋ฐ๋ก๋ฐ๋ก ์ธ์ง ํ์ธ
l2.set(1, new Integer(100)); // ๋ณต์ฌ๋ ๋ฆฌ์คํธ์ ๋ค๋ฅธ ๊ฐ์ ๋์ฒด
l2.add(new Integer(200)); // ๋ณต์ฌ๋ ๋ฆฌ์คํธ์ ๋ค๋ฅธ ๊ฐ์ ์ถ๊ฐ
// toStirng์ ์ฌ์ ์ํ์์ผ๋ ๋ฐฐ์ด์ ์์๊ฒ ์ถ๋ ฅ
System.out.println(l);
System.out.println(l2);
}

toArray ๊ตฌํํ๊ธฐ
์ค์ ๋ฆฌ์คํธ๋ฅผ ๋ฐฐ์ด๋ก ๋ณํํ๋ toArray() ๋ฉ์๋์๋ ๋๊ฐ์ง ์ข
๋ฅ๋ก ์ด์ฉ๋๋ค.
Object[] toArray(): ๋ฆฌ์คํธ๋ฅผ Object[] ๋ฐฐ์ด๋ก ๋ณํํ๊ณ ๊ทธ๋๋ก ๋ฐํT[] toArray(T[] a): ๋ฆฌ์คํธ๋ฅผ T[] ๋ฐฐ์ด๋ก ๋ณํํ๊ณ ๋งค๊ฐ๋ณ์ a์ ์ฝ์
public static void main(String[] args) {
ArrayList<Integer> list = new ArrayList<>(Arrays.asList(1,2,3));
// get list to array (toArray())
Object[] copy1 = list.toArray(); // list๋ฅผ ๋ฐฐ์ด๋ก ๋ณํํ๊ณ ๋ฐํ
System.out.println(Arrays.toString(copy1)); // [1, 2, 3]
// get list to array (toArray(T[] a)
Integer[] copy2 = new Integer[10];
Integer[] array = { 100,200,300,400,500,600 };
copy2 = list.toArray(array); // list๋ฅผ ๋ฐฐ์ด๋ก ๋ณํํ๊ณ ๋งค๊ฐ๋ณ์๋ก ๋ฐ์ ๋ฐฐ์ด์ ๋ผ์๋ฃ๊ธฐ
System.out.println(Arrays.toString(copy2)); // [1, 2, 3, null, 500, 600]
}
๋ง์ง๋ง ๋ฐฐ์ด ์ถ๋ ฅ์์ null์ด ์ฝ์ ๋์ด ์๋ ์ด์ ๋ ์๋ฐ ๋ฉ์๋ ์คํ์ด๋ค.
javadoc์ ๋ฐ๋ฅด๋ฉด ์ฝ์ ๋ ๋ฆฌ์คํธ์ ๊ธธ์ด๋ฅผ ์๋ฆฌ๊ธฐ ์ํด์ ์ผ๋ถ๋ก null์ ๋ฃ๊ธฐ ์ํด์ ๋ผ๊ณ ํ๋ค.
toArray() ๊ตฌํ
public Object[] toArray() {
// Arrays.copyOf(์๋ณธ ๋ฐฐ์ด, ๋ณต์ฌํ ๊ธธ์ด)
return Arrays.copyOf(elementData, size);
}
toArray(T[] a) ๊ตฌํ
- ์ด ๋ถ๋ถ์ ์ ๋ค๋ฆญ ๋ฉ์๋ ์ด๋ฏ๋ก ๋
๋ฆฝ์ ์ธ ํ์
ํ๋ผ๋ฏธํฐ
<T>๋ฅผ ๊ฐ๋๋ค. - ์ธ์๋ก ๋ค์ด์จ ๋ฐฐ์ด์ ๊ณต๊ฐ์ด size๋ณด๋ค ํฌ๋ ํฌ์ง ์๋๋์ ๋ฐ๋ผ ๋ถ๊ธฐ๊ฐ ๊ฐ๋ฆฌ๊ฒ ๋๋ค.
- ์ฒซ๋ฒ์งธ ๋ถ๊ธฐ์์๋ ํ๋ผ๋ฏธํฐ ๋ฐฐ์ด์ ๊ธธ์ด๊ฐ ํด๋น ArrayList ๊ฐ์ฒด์ size ๋ณด๋ค ์๊ธฐ ๋๋ฌธ์ ๊ทธ๋ฅ ๊ณ ๋๋ก ๋ณต์ฌํด์ ๋ฐํํด์ฃผ๋ฉด ๋๋ค.
- ๋๋ฒ์งธ ๋ถ๊ธฐ์์๋ ํ๋ผ๋ฏธํฐ ๋ฐฐ์ด์ ๊ธธ์ด๊ฐ ํด๋น ArrayList ๊ฐ์ฒด์ size ๋ณด๋ค ํฌ๊ฑฐ๋ ๊ฐ์ ๊ฒฝ์ฐ, ํ๋ผ๋ฏธํฐ ๋ฐฐ์ด์ ์์๋ค์ ์ ์งํ์ฑ๋ก, ๋ฆฌ์คํธ ์์๋ค๋ง ์ฝ์
ํ๋ ๋์์ด ํ์ํ๋ค. ๋ฐ๋ณต๋ฌธ์ผ๋ก ๊ตฌํํ ์๋ ์์ง๋ง
System.arraycopy()๋ฉ์๋๋ฅผ ํตํด ๊ฐ๋จํ ๊ตฌํํ๋ค. - null ํ ๋น ๋ถ๋ถ์ ์์งํ ์ ์๋ ๊ฑด์ง ๋ชจ๋ฅด๊ฒ ์ง๋ง ์คํ์ด๋๊น ๊ตฌํํด์ค๋ค. (์ด๋๊น์ง ํ ๋น๋์๋๋๋ฅผ null ํ์๋ฅผ ํตํด ์๋ ค์ฃผ๊ธฐ ์ํด ์คํ์ ์ ๋ฆฌ ์ค๊ณ๋จ)
@SuppressWarnings("unchecked")
public <T> T[] toArray(T[] arr) {
// ๋ง์ฝ ์ธ์๋ก ๋ฐ์ ๋ฐฐ์ด ๊ณต๊ฐ์ด ์์ ๊ฒฝ์ฐ
if(arr.length < size) {
// Arrays.copyOf(์๋ณธ ๋ฐฐ์ด, ๋ณต์ฌํ ๊ธธ์ด)
return (T[]) Arrays.copyOf(elementData, size);
}
// ๋ง์ฝ ์ธ์๋ก ๋ฐ์ ๋ฐฐ์ด ๊ณต๊ฐ์ด ํฐ ๊ฒฝ์ฐ
else {
// System.arraycopy(์๋ณธ๋ฐฐ์ด, ์๋ณธ๋ฐฐ์ด ์์์์น, ๋ณต์ฌํ ๋ฐฐ์ด, ๋ณต์ฌํ ๋ฐฐ์ด ์์์์น, ๋ณต์ฌํ ์์ ์)
System.arraycopy(elementData, 0, arr, 0, size);
if(arr.length > size) arr[size] = null;
return arr;
}
}
ArrayList ๊ตฌํ ์ ์ฒด ์ฝ๋
MyList.java
public interface MyList<T> {
boolean add(T value); // ์์๋ฅผ ์ถ๊ฐ
void add(int index, T value); // ์์๋ฅผ ํน์ ์์น์ ์ถ๊ฐ
boolean remove(Object value); // ์์๋ฅผ ์ญ์
T remove(int index); // ํน์ ์์น์ ์๋ ์์๋ฅผ ์ญ์
T get(int index); // ์์ ๊ฐ์ ธ์ค๊ธฐ
void set(int index, T value); // ํน์ ์์น์ ์๋ ์์๋ฅผ ์ ์์๋ก ๋์ฒด
boolean contains(Object value); // ํน์ ์์๊ฐ ๋ฆฌ์คํธ์ ์๋์ง ์ฌ๋ถ๋ฅผ ํ์ธ
int indexOf(Object value); // ํน์ ์์๊ฐ ๋ช ๋ฒ์งธ ์์น์ ์๋์ง๋ฅผ ๋ฐํ (์์ฐจ ๊ฒ์)
int lastIndexOf(Object o); // ํน์ ์์๊ฐ ๋ช ๋ฒ์งธ ์์น์ ์๋์ง๋ฅผ ๋ฐํ (์ญ์ ๊ฒ์)
int size(); // ์์์ ๊ฐ์๋ฅผ ๋ฐํ
boolean isEmpty(); // ์์๊ฐ ๋น์ด์๋์ง
public void clear(); // ์์๋ฅผ ๋ชจ๋ ์ญ์
}
MyListIterator.java
public interface MyListIterator<T> {
T next();
boolean hasNext();
T previos();
boolean hasPrevios();
void add(Object element);
void remove();
}
MyArrayList.java
class MyArrayList<E> implements MyList<E> {
private static final int DEFAULT_CAPACITY = 5; // ์์ฑ์๋ก ๋ฐฐ์ด์ด ์์ฑ๋ ๋ ๊ธฐ๋ณธ ์ฉ๋
private static final Object[] EMPTY_ELEMENTDATA = {}; // ๋น ๋ฐฐ์ด
private int size; // elementData ๋ฐฐ์ด์ ์ด ์์ ๊ฐ์๋ฅผ ๋ํ๋ด๋ ๋ณ์
Object[] elementData; // ์๋ฃ๋ฅผ ๋ด์ ๋ด๋ถ ๋ฐฐ์ด
// ์์ฑ์ (์ด๊ธฐ ๊ณต๊ฐ ํ ๋น X)
public MyArrayList() {
this.elementData = new Object[DEFAULT_CAPACITY]; // ๋ํดํธ ์ฉ๋์ผ๋ก ์ด๊ธฐํ
this.size = 0;
}
// ์์ฑ์ (์ด๊ธฐ ๊ณต๊ฐ ํ ๋น O)
public MyArrayList(int capacity) {
// ํ๋ผ๋ฏธํฐ์ ๊ฐ์ด ์์์ผ ๊ฒฝ์ฐ ๊ทธ๋๋ก ์ฉ๋์ผ๋ก ๋ฐฐ์ด์ ์์ฑ
if (capacity > 0) {
this.elementData = new Object[capacity];
}
// ํ๋ผ๋ฏธํฐ์ ๊ฐ์ด 0์ผ ๊ฒฝ์ฐ ์ธ์๋ฅผ ์ฃผ์ง ์๊ณ ์ธ์คํด์คํ ํ ๊ฒ๊ณผ ๊ฐ์ผ๋ ๋ํดํธ ์ฉ๋์ผ๋ก ์ด๊ธฐํ
else if (capacity == 0) {
this.elementData = new Object[DEFAULT_CAPACITY];
}
// ํ๋ผ๋ฏธํฐ์ ๊ฐ์ ์์๋ก ์ค์ ํ ๊ฒฝ์ฐ ์์ธ๋ฅผ ๋ฐ์์ํค๋๋ก ์์ ํ๊ฒ ์ค๊ณ
else if (capacity < 0) {
throw new RuntimeException(new IllegalAccessException("๋ฆฌ์คํธ ์ฉ๋์ ์๋ชป ์ค์ ํ์์ต๋๋ค")); // Checked ์์ธ๋ฅผ Unchecked ์์ธ๋ก ๋ณํ
}
this.size = 0;
}
// ํด๋์ค ๋ด๋ถ์์๋ง ์คํ๋๋ ๋ฉ์๋์ด๋ private
private void resize() {
int element_capacity = elementData.length; // ํ์ฌ ๋ฐฐ์ด์ ํฌ๊ธฐ๋ฅผ ์ป์
// ์ฉ๋์ด ๊ฝ์ฐฌ ๊ฒฝ์ฐ
if (element_capacity == size) {
int new_capacity = element_capacity * 2; // ๋๋ํ๊ฒ ๊ณต๊ฐ์ ์ ์งํ๊ธฐ ์ํด ํ์ฌ ์ฉ๋์ ๋๋ฐฐ๋ก ์ค์
elementData = Arrays.copyOf(elementData, new_capacity); // ๋ณต์ฌํ ๋ฐฐ์ด์ new_capacity ์ฉ๋ ๋งํผ ์ค์ ํ๊ณ elementData ์์๋ค์ ์ ์ฒด ๋ณต์ฌํด์ ๋ฃ๊ณ ๋ฐํ (๋น๊ณต๊ฐ์ null)
return;
}
// ์ฉ๋์ ๋นํด ๋ฐ์ดํฐ ์์ด ์ ์ ๊ฒฝ์ฐ
if ((element_capacity / 2) > size) {
int half_capacity = element_capacity / 2;
elementData = Arrays.copyOf(elementData, Math.max(half_capacity, DEFAULT_CAPACITY)); // half_capacity ์ ๋ํดํธ ์ฉ๋ ์ค ํฐ๊ฑธ ๋ณต์ฌ
return;
}
// ๋ค์ด์๋ ๋ฐ์ดํฐ๊ฐ ํ๋๋ ์์ ๊ฒฝ์ฐ (๋น ๋ฐฐ์ด ์ผ๊ฒฝ์ฐ)
if (Arrays.equals(elementData, EMPTY_ELEMENTDATA)) {
elementData = new Object[DEFAULT_CAPACITY]; // ๊ธฐ๋ณธ ์ฉ๋์ผ๋ก ์ด๊ธฐํ
return;
}
}
@Override
public boolean add(Object value) {
resize(); // ํ์ฌ ๋ฐฐ์ด์ด ๊ฝ ์ฐจ์๋ ์ํ์ด๋ฉด ๋ฆฌ์ฌ์ด์ง
elementData[size] = value; // size๊ฐ ์์์ ๊ฐฏ์์ด๊ณ , ๋ฐฐ์ด์ ์ธ๋ฑ์ค๋ 0๋ถํฐ ์์ํ๋ ๊ฒฐ๊ตญ ์ถ๊ฐํ ์ ์๋ ๋ง์ง๋ง ์์น๋ฅผ ๊ฐ๋ฆฌํค๊ฒ ๋๋ค.
size++; // ์์๊ฐ ์ถ๊ฐ๋์์ผ๋, ๋ฐฐ์ด ํฌ๊ธฐ๋ฅผ ๋ํ๋ด๋ size๋ ์ฌ๋ฆฐ๋ค.
return true;
}
@Override
public void add(int index, Object value) {
// ์ธ๋ฑ์ค๊ฐ ์์์ด๊ฑฐ๋, ๋ฐฐ์ด ํฌ๊ธฐ(size)๋ฅผ ๋ฒ์ด๋ ๊ฒฝ์ฐ ์์ธ ๋ฐ์ (๋ฆฌ์คํธ๋ ๋ฐ์ดํฐ๊ฐ ์ฐ์๋์ด์ผํจ)
if (index < 0 || index > size) {
throw new IndexOutOfBoundsException();
}
// ์ธ๋ฑ์ค๊ฐ ๋ง์ง๋ง ์์น์ผ ๊ฒฝ์ฐ
if (index == size) {
add(value); // ๊ทธ๋ฅ ์ถ๊ฐ
}
// ์ธ๋ฑ์ค๊ฐ ์ค๊ฐ ์์น๋ฅผ ๊ฐ๋ฆฌํฌ ๊ฒฝ์ฐ
else {
resize(); // ํ์ฌ ๋ฐฐ์ด์ด ๊ฝ ์ฐจ์๋ ์ํ์ด๋ฉด ๋ฆฌ์ฌ์ด์ง
// ๋ฃจํ๋ณ์์ ๋ฐฐ์ด ํฌ๊ธฐ๋ฅผ ๋ฃ๊ณ , index ์์น ๊น์ง ์ํํด์ ์์๋ค ํ ์นธ ์ฉ ๋ค๋ก ๋ฐ์ด ๋น ๊ณต๊ฐ ๋ง๋ค๊ธฐ
for (int i = size; i > index; i--) {
elementData[i] = elementData[i - 1];
}
elementData[index] = value; // index ์์น์ ์์ ํ ๋น
size++;
}
}
@Override
@SuppressWarnings("unchecked")
public E remove(int index) {
// 1. ์ธ๋ฑ์ค๊ฐ ์์์ด๊ฑฐ๋, size ๋ณด๋ค ๊ฐ๊ฑฐ๋ ํด๊ฒฝ์ฐ (size์ ๊ฐ๋ค๋ ๋ง์ ์์ ์์น๊ฐ ๋น๊ณต๊ฐ ์ด๋ผ๋ ๋ง)
if (index < 0 || index >= size) {
throw new IndexOutOfBoundsException();
}
// 2. ๋ฐํํ ๊ฐ ๋ฐฑ์
E element = (E) elementData[index];
// 3. ์์ ์ ๊ฑฐ (๋ช
์์ ์ผ๋ก ์์๋ฅผ null๋ก ์ฒ๋ฆฌํด์ฃผ์ด์ผ GC๊ฐ ์๊ฑฐํด๊ฐ)
elementData[index] = null;
// 4. ๋ฐฐ์ด ์์ ์ด๋ (์ญ์ ํ ์์์ ๋ค์ ์๋ ๋ชจ๋ ์์๋ค์ ํ ์นธ์ฉ ๋น๊ฒจ์ด)
for (int i = index; i < size - 1; i++) {
elementData[i] = elementData[i + 1];
elementData[i + 1] = null;
}
// 5. ์์๋ฅผ ์ ๊ฑฐํ์ผ๋ size๋ ๊ฐ์
size--;
// 6. ํ์ฌ ๋ฐฐ์ด์ด capacity๊ฐ ๋๋ฌด ๋จ์๋๋ ์ํ์ด๋ฉด ๋ฆฌ์ฌ์ด์ง
resize();
// 7. ๋ฐฑ์
ํ ์ญ์ ๋ ์์๋ฅผ ๋ฐํ
return element;
}
@Override
public boolean remove(Object value) {
// 1. ๋จผ์ ํด๋น ์์๊ฐ ๋ช๋ฒ์งธ ์์น์ ์กด์ฌํ๋์ง ์ธ๋ฑ์ค๋ฅผ ์ป์ด์จ๋ค.
int idx = indexOf(value);
// 2. ๋ง์ฝ ๊ฐ์ด -1์ด๋ฉด ์ญ์ ํ๊ณ ์ ํ๋ ๊ฐ์ด ์๋ ๊ฒ์ด๋ ๊ทธ๋๋ก ๋ฉ์๋๋ฅผ ์ข
๋ฃํ๋ค.
if (idx == -1) return false;
// 3. ์ธ๋ฑ์ค๋ฅผ ์ฐพ์์ผ๋ฉด ๊ทธ๋๋ก remove() ๋ฉ์๋๋ก ๋๊ฒจ ์ญ์ ํ๋ค.
remove(idx);
return true;
}
@SuppressWarnings("unchecked")
@Override
public E get(int index) {
if (index < 0 || index >= size) {
throw new IndexOutOfBoundsException();
}
return (E) elementData[index]; // ์์๊ฐ ๋ฐํ (ํ๋ณํ ํ์)
}
@Override
public void set(int index, Object value) {
if (index < 0 || index >= size) {
throw new IndexOutOfBoundsException();
}
elementData[index] = value; // ์์ ๊ต์ฒด
}
@Override
public int indexOf(Object value) {
// ๋งค๊ฐ๋ณ์๊ฐ null ์ผ๊ฒฝ์ฐ (null ๋น๊ต๋ ๋๋ฑ์ฐ์ฐ์๋ก ํํ๊ธฐ ๋๋ฌธ์ ๋น๊ต ๋ก์ง์ ๋ถ๋ฆฌ)
if (value == null) {
for (int i = 0; i < size; i++) {
if (elementData[i] == null) {
return i; // ์ธ๋ฑ์ค ๋ฐํ
}
}
}
// ๋งค๊ฐ๋ณ์๊ฐ ์ค์ง์ ์ธ ๊ฐ์ผ ๊ฒฝ์ฐ
else {
for (int i = 0; i < size; i++) {
if (elementData[i].equals(value)) {
return i; // ์ธ๋ฑ์ค ๋ฐํ
}
}
}
return -1; // ์ฐพ์ ๊ฐ์ด ์์ ๊ฒฝ์ฐ
}
@Override
public int lastIndexOf(Object value) {
if (value == null) {
for (int i = size - 1; i >= 0; i--) {
if (elementData[i] == null) {
return i; // ์ธ๋ฑ์ค ๋ฐํ
}
}
} else {
for (int i = size - 1; i >= 0; i--) {
if (elementData[i].equals(value)) {
return i; // ์ธ๋ฑ์ค ๋ฐํ
}
}
}
return -1; // ์ฐพ์ ๊ฐ์ด ์์ ๊ฒฝ์ฐ
}
@Override
public int size() {
return size;
}
@Override
public boolean isEmpty() {
return size == 0;
}
@Override
public void clear() {
elementData = new Object[DEFAULT_CAPACITY]; // ๊ธฐ๋ณธ ์ฉ๋์ผ๋ก ์ด๊ธฐํ
size = 0; // ๋ชจ๋ ์์๋ฅผ ์ง์ ์ผ๋ size๋ ์ด๊ธฐํ
}
@Override
public boolean contains(Object value) {
// ์ธ๋ฑ์ค๊ฐ์ด 0๋ณด๋ค ํฌ๋ฉด ๊ณง ์์์ ์์น๋ก์ ์์๊ฐ ์กด์ฌํ๋ค๋ ๊ฒ์ด๊ณ , 0๋ณด๋ค ์์ผ๋ฉด -1 ๋ก์ ์์๊ฐ ์กด์ฌํ์ง ์๋๋ค๋ ๊ฒ์ด๋ค.
return indexOf(value) >= 0 ? true : false;
}
@Override
public String toString() {
return Arrays.toString(elementData);
}
class ListIterator implements MyListIterator<E> {
private int nextIndex = 0; // ์ปค์ ์์น
@Override
public boolean hasNext() {
// nextIndex๊ฐ ๋ฐฐ์ด ์ฌ์ด์ฆ๋ณด๋ค ์๋ค๋ ๊ฒ์ ์ํํ ์์๊ฐ ๋จ์์๋ค๋ ๋ป
return nextIndex < size();
}
@Override
@SuppressWarnings("unchecked")
public E next() {
// ๋ฐฐ์ด ์์๋ฅผ ๋ฐํํ๊ณ nextIndex 1 ์ฆ๊ฐ
return (E) elementData[nextIndex++];
}
@Override
public boolean hasPrevios() {
// nextIndex๊ฐ 0๋ณด๋ค ํฌ๋ฉด ์ด์ ์์๊ฐ ๋จ์์๋ค๋ ๋ป
return nextIndex > 0; // ์ธ๋ฑ์ค๊ฐ 0๋ถํฐ ๋ผ๊ณ ํด์ >= 0 ์ด ์๋๋ค. previous ๋ฉ์๋์์ --nextIndex๋ฅผ ํ๊ธฐ ๋๋ฌธ์ 0๋ณด๋ค ๋ฌด์กฐ๊ฑด ์ปค์ผ๋๋ค.
}
@Override
@SuppressWarnings("unchecked")
public E previos() {
// ๋ฐฐ์ด ์์๋ฅผ ๋ฐํํ๊ณ nextIndex 1 ๊ฐ์
return (E) elementData[--nextIndex]; // ์ด๋ ์ฆ๊ฐ์ฐ์ฐ์๋ฅผ ์์๋ค ๋ถ์ฌ์ฃผ์ด์ผ ํ๋ค
}
@Override
public void add(Object element) {
// ์ดํฐ๋ ์ดํฐ ์ปค์ ์์น์ ์์๋ฅผ ์ถ๊ฐ
MyArrayList.this.add(nextIndex, element);
}
@Override
public void remove() {
// ์ดํฐ๋ ์ดํฐ ์ปค์ ์์น์ ์ ์์๋ฅผ ์ ๊ฑฐ (next ๋ฉ์๋ ์์ฒด๊ฐ ํ์ฌ ์์น์ ์์๋ฅผ ๋ฐํํ๊ณ ์ปค์๋ฅผ 1 ๋ํ๋๊น)
MyArrayList.this.remove(nextIndex - 1);
// ์์๊ฐ ๋ฐฐ์ด์์ ์ ๊ฑฐ ๋์์ผ๋ size๊ฐ ์ค์ด๋ ๋ค. ๊ทธ๋ฆฌ๊ณ ์ปค์๋ ์์ผ๋ก ๋น๊ฒจ์ผ ํ๋ค. (์์๊ฐ ์ ๊ฑฐ๋์์ผ๋๊น)
nextIndex--;
}
}
// ๋ด๋ถ ํด๋์ค ListIterator ๊ฐ์ฒด๋ฅผ ๋ง๋ค์ด ๋ฐํ
public ListIterator listIterator() {
return new ListIterator();
}
@Override
public Object clone() throws CloneNotSupportedException {
// 1. MyArrayList ์์ฒด๋ฅผ ๋ณต์ฌํ์ฌ ๋ณ์์ ์ ์ฅ
MyArrayList<?> cloneList = (MyArrayList<?>) super.clone();
// 2. ๋ณต์ฌํ MyArrayList์ Object ๋ฐฐ์ด์ ์ฌ์ด์ฆ๋ฅผ ๋ฏธ๋ฆฌ ์ง์ ํ์ฌ ์ฌ์์ฑ
cloneList.elementData = new Object[size];
// 3. ๋ฆฌ์คํธ์ ์ ์ฅํ๋ ๋ฐ์ดํฐ๋ ๊ฐ์ฒด(reference ํ์
)์ด๊ธฐ ๋๋ฌธ์ ๋ฐ๋์ ์์ ์์๋ค๋ ๋ฐ๋ก๋ฐ๋ก ๋ณต์ฌ๋ฅผ ํด์ค์ผ ํจ
cloneList.elementData = Arrays.copyOf(elementData, size); // ์๋ก์ด ๋ฐฐ์ด = Arrays.copyof(์๋ณธ ๋ฐฐ์ด, ์๋ณธ ๋ฐฐ์ด์์ ๋ณต์ฌํ๊ณ ์ถ์ ์์๋ค์ ๋ฒ์);
return cloneList;
}
public Object[] toArray() {
return Arrays.copyOf(elementData, size());
}
@SuppressWarnings("unchecked")
public <T> T[] toArray(T[] arr) {
// ๋ง์ฝ ์ธ์๋ก ๋ฐ์ ๋ฐฐ์ด ๊ณต๊ฐ์ด ๋ด๋ถ ๋ฐฐ์ด๋ณด๋ค ์์ ๊ฒฝ์ฐ
if (arr.length <= size) {
return (T[]) Arrays.copyOf(elementData, size); // ๊ทธ๋ฅ ๋ณต์ฌํด์ ๋ฐํ
}
// ๋ง์ฝ ์ธ์๋ก ๋ฐ์ ๋ฐฐ์ด ๊ณต๊ฐ์ด ํฐ ๊ฒฝ์ฐ
else {
// System.arraycopy(์๋ณธ๋ฐฐ์ด, ์๋ณธ๋ฐฐ์ด ์์์์น, ๋ณต์ฌํ ๋ฐฐ์ด, ๋ณต์ฌํ ๋ฐฐ์ด ์์์์น, ๋ณต์ฌํ ์์ ์)
System.arraycopy(elementData, 0, arr, 0, size);
// ๋ด๋ถ ๋ฐฐ์ด์ ๋ณต์ฌํ ํ ๋ฐ๋ก ๋ค์์ null์ ์ฝ์
if (arr.length > size)
arr[size] = null;
return arr;
}
}
}
๋ง์ง๋ง์ผ๋ก ์ง์ ๊ตฌํํด๋ณธ MyArrayList ์ปฌ๋ ์ ์ ์ด์ฉํด ์ ๋ง๋ก ์ค์ ArrayList ์ฒ๋ผ ๋์ํ๋์ง ํ ์คํธ๋ฅผ ํด๋ณด์.
public static void main(String[] args) {
MyArrayList<Number> list = new MyArrayList<>(); // ์ด๊ธฐ capatity๋ 5
list.add(1);
list.add(2);
list.add(2);
list.add(3);
list.add(4);
list.add(1, 1.5); // 6๋ฒ์งธ ์์๋ฅผ ์ถ๊ฐํจ์ผ๋ก์ ๋ฆฌ์คํธ๊ฐ ํ์ฅ๋จ
System.out.println(list); // [1, 1.5, 2, 2, 3, 4, null, null, null, null]
System.out.println(list.indexOf(2)); // 2
System.out.println(list.lastIndexOf(2)); // 3
System.out.println(list.remove(0)); // 1
System.out.println(list.remove(2)); // 2
System.out.println(list); // [1.5, 2, 3, 4, null] - size์ ๋นํด capacity๊ฐ ๋จ์๋์ ๋ฆฌ์คํธ๊ฐ ์ถ์๋จ (๋ฉ๋ชจ๋ฆฌ ์ต์ ํ)
System.out.println(list.remove(Integer.valueOf(1))); // false
System.out.println(list.remove(Integer.valueOf(2))); // true
System.out.println(list); // [1.5, 3, 4, null, null]
list.clear();
System.out.println(list); // [null, null, null, null, null]
}
public static void main(String[] args) {
MyArrayList<Number> list = new MyArrayList<>(); // ์ด๊ธฐ capatity๋ 5
list.add(1);
list.add(2);
list.add(3);
list.add(4);
list.add(5);
System.out.println(list); // [1, 2, 3, 4, 5]
// ๋ฆฌ์คํธ ์ดํฐ๋ ์ดํฐ ๊ฐ์ฒด ๋ฐํ
MyListIterator<Number> listItr = list.listIterator();
while(listItr.hasNext()) {
System.out.println(listItr.next());
}
/*
1
2
3
4
5
*/
while(listItr.hasPrevios()) {
System.out.println(listItr.previos());
}
/*
5
4
3
2
1
*/
listItr.add(999);
System.out.println(list); // [999, 1, 2, 3, 4, 5, null, null, null, null]
}
# ์ฐธ๊ณ ์๋ฃ
https://youtu.be/bmPRG34FPZY
https://youtu.be/1R8H-T1u-7E
https://www.w3resource.com/java-tutorial/arraylist/arraylist_add-element-index.php
์ด ๊ธ์ด ์ข์ผ์ จ๋ค๋ฉด ๊ตฌ๋ & ์ข์์
์ฌ๋ฌ๋ถ์ ๊ตฌ๋
๊ณผ ์ข์์๋
์ ์์๊ฒ ํฐ ํ์ด ๋ฉ๋๋ค.