사이먼's 코딩노트

[Java] ArrayList 본문

Java/Java

[Java] ArrayList

simonpark817 2024. 3. 18. 21:53

[ArrayList]

  • Java에는 기본적으로 ArrayList 클래스가 import 되어있다.
  • 우리는 보통 ArrayList를 사용하기 위해서 코드 가장 상단에 [import java.util.ArrayList;] 라는 코드를 작성한다.
  • 하지만 이번엔 ArrayList 클래스의 생성 과정을 간략하게나마 알아보기 위해 직접 ArrayList 클래스를 작성하면서 이해를 해봅시다.
  • 해당 과정을 실제로 쓸 일은 없지만, ArrayList에 대한 이해도를 높이기 위한 과정이라고 생각하면 좋다.

 

  • 먼저, 아래 Main 메서드를 보고 해당 코드가 에러가 나지않고 원하는 출력문이 나오도록 ArrayList 클래스를 추가하여봅시다.
  • 조건은 선언된 배열의 크기를 3으로 지정하는 것입니다.
public class Main {
    public static void main(String[] args) {
        ArrayList ar = new ArrayList();
        ar.add(100);
        ar.add(200);
        ar.add(300);
        ar.add(400);

        int value = ar.get(0);
        System.out.println(value);
        // 출력 : 100

        value = ar.get(1);
        System.out.println(value);
        // 출력 : 200

        value = ar.get(2);
        System.out.println(value);
        // 출력 : 300

        value = ar.get(3);
        System.out.println(value);
        // 출력 : 400
    }
}

 

  • 아래는 위의 코드가 정상적으로 실행되기 위해 작성한 ArrayList 클래스이다.
class ArrayList {
    int lastIndex;
    int[] arr;

    ArrayList() {
        lastIndex = -1;
        arr = new int[3];
    }

    boolean isFull() {
        return lastIndex + 1 == arr.length;
    }

    void sizeUpArr() {
        int[] newArr = new int[arr.length * 2];

        for(int i = 0; i < arr.length; i++) {
            newArr[i] = arr[i];
        }
        arr = newArr;
    }

    void add(int data) {
        lastIndex++;

        if(isFull()) {
            sizeUpArr();
        }

        arr[lastIndex] = data;
    }

    int get(int index) {
        return arr[index];
    }
}
  • 먼저 Main 메서드가 실행되기 위한 가장 최소한의 조건은 add() 와 get() 메서드가 있어야한다.
  • add() 메서드의 역할은 배열에 0번부터 차례대로 값을 저장하는 것이고, get() 메서드의 역할은 원하는 배열 인덱스의 값을 꺼내오는 것이다.
  • add() 에 값을 저장하기 위해선 일단 index 번호가 필요하고 새로운 배열이 필요하다.
  • 전역변수로 lastIndex와 arr 배열을 생성하고 생성자에서 lastIndex는 초기값을 -1, arr는 int 타입이며 공간이 최대 3개인 배열로 만들어준다.
  • add() 에서는 먼저 lastIndex 값을 1씩 증가시켜준다. 그 이유는 배열은 index 번호가 0번부터 이기 때문에 -1로 초기화된 값을 하나씩 증가시켜야한다. 그 다음 각 lastIndex 번호에 맞게 차례대로 배열 공간에 인자로 넘겨받는 data 값을 저장하면 add() 가 올바르게 동작한다.
  • get() 는 Main 메서드에서 보면 int value 변수에 해당 값을 저장해야되기 때문에 메서드의 타입을 int로 정하고 return 값을 받아야한다. 인자로 index 번호를 넘겨주기 때문에 해당 index 번호에 위치한 배열의 값인 arr[index]를 return 해주면 get() 이 올바르게 동작한다.
  • 하지만 여기서 문제는 사실 3개의 배열 공간에만 값을 저장하고 빼내는 것이 아니라 총 4개의 배열 공간에 값을 저장하고 빼내고 있다.
  • 그렇기 떄문에 조건문을 이용해서 배열 공간이 사용자가 지정한 개수를 초과하면 더 공간이 넓어진 새로운 배열로 교체해주는 작업이 필요하다.
  • 먼저 add() 에서 lastIndex 값을 하나씩 증가시킨 후 만약 배열의 길이가 초과했는지 isFull() 메서드를 통해 참과 거짓을 구분하고 만약 초과했다면 sizeUpArr() 메서드를 통해 배열 크기를 늘려주는 과정을 거친다.
  • isFull() 은 참과 거짓을 return 하기 때문에 메서드 타입은 boolean이고, return 값으로 lastIndex + 1 값이 arr.length 랑 같다면 true가 되도록 한다.
  • sizeUpArr() 는 newArr 라는 새로운 배열을 만들어 주고 이 때, 배열의 크기는 기존에 있던 arr보다 2배 많도록 한다.
  • 그 다음 반복문을 통해 기존에 arr 배열에 있던 값들을 newArr로 이전시켜준다.
  • 마지막으로 새로 만들어진 newArr의 리모콘을 arr로 옮겨주면 크기에 제한없이 계속해서 add와 get이 가능하게 된다.

 

[size()]

int ar_size = ar.size();
System.out.println(ar_size);
  • 만약 Main 메서드에 위와 같은 코드가 추가된다면, size() 메서드를 어떻게 구현해야 될까?

 

int size() {
    return lastIndex + 1;
}
  • size() 메서드는 배열의 크기를 출력하는 역할로서, 메서드를 int 타입으로 생성하고 lastIndex가 아닌 lastIndex에 1을 더한 값을 return 해줘야한다.

 

[remove()]

ar.remove(2);
int value = ar.get(2);
System.out.println(value);
  • 만약 Main 메서드에 위와 같은 코드가 추가된다면, remove() 메서드를 어떻게 구현해야 될까?

 

void remove(int index) {
    for(int i = index; i < lastIndex; i++) {
        arr[i] = arr[i + 1];
    }
    lastIndex--;
}
  • remove는 제거한다는 뜻으로 여기선 특정 index 위치의 배열 값을 삭제한다는 뜻이다.
  • 매개변수로는 index 번호 값을 받고, 만약 remove(2) 라면 2번째 배열에 위치한 300이라는 값을 삭제하고 get(2)로 다시 2번째 배열에 위치한 값을 불러올 때 300이 아닌 그 다음 index 번호에 위치한 배열의 값 400이 출력되어야 한다.
  • 다시 말해 remove로 제거되면 하나씩 index 번호가 앞댕겨져서 저장된다는 뜻이다.
  • 그러기 위해선 특정 index 번호부터 현재 최대 번호인 lastIndex까지 반복하면서 하나씩 값을 앞댕겨 주고 하나의 데이터가 삭제되었기 때문에 lastIndex 값도 1씩 감소시켜준다.

 

[addAt()]

ar.addAt(600, 2);
ar.addAt(700, 0);
  • 만약 Main 메서드에 위와 같은 코드가 추가된다면, addAt() 메서드를 어떻게 구현해야 될까?

 

void addAt(int data, int index) {
    lastIndex++;

    if(isFull()) {
        sizeUpArr();
    }

    for(int i = lastIndex; i > index; i--) {
        arr[i] = arr[i - 1];
    }

    arr[index] = data;
}
  • addAt은 데이터를 배열에 새로 추가는 하지만 매개변수로 data와 index 두 개를 받아, 사용자가 원하는 index 번호 위치에 data를 넣는다는 뜻이다.
  • 만약 addAt(600,2) 라면 2번째 위치에 해당하는 배열의 값인 300을 밀어내고 그 자리에 600이라는 값을 저장하겠다는 뜻이다. 한마디로 새치기하는 것이다.
  • 그러기 위해선 일단 기존 add() 와 동일하게 lastIndex 값 증가 후, 배열 크기가 모자라지 않는지 확인한다.
  • 그 다음 현재 최대 번호인 lastIndex 번호부터 새치기하고 싶은 위치인 index 번호까지 하나씩 값을 뒤로 미뤄주고 원하는 배열의 위치에 data 값을 넣어준다.
반응형

'Java > Java' 카테고리의 다른 글

[Java] 인터페이스  (2) 2024.03.19
[Java] 제네릭 / HashMap / 정리  (0) 2024.03.18
[Java] 배열 / toString / equals / StringBuilder  (2) 2024.03.14
[Java] 형변환 문제풀이  (0) 2024.03.13
[Java] 형변환(래퍼클래스 / Object)  (0) 2024.03.13