1. ArrayList란?

  • 선언시 크기가 고정되어 있다.
  • 주소가 순차적으로 배열되어 있다.
  • 인덱스를 통하여 접근하므로 속도가 빠르다.

2. ArrayList 구현하기

구현할 기능은 아래와 같다.

  • add (int i, E x) - i번째 인덱스에 원소 x를 입력한다.
  • append (E x) - 배열 리스트의 끝에 원소 x를 입력한다.
  • remove (int i) - i번째 원소를 삭제한다.
  • removeItem (E x) - 배열 리스트에서 원소 x를 삭제한다. 중복 원소가 있을 경우 먼저 나오는 원소를 삭제한다.
  • get (int i) - i번째 원소를 리턴한다.
  • set (int i, E x) - i번째 인덱스의 원소를 x로 교체한다.
  • len() - 배열 리스트의 원소 개수를 리턴한다.
  • isEmpty() - 배열 리스트가 비었는지 여부를 boolean으로 리턴한다.
  • clear() - 인덱스를 비운다.
  • indexOf(E x) - 배열 리스트 원소 x의 인덱스를 리턴한다. 중복 원소가 있을 경우 먼저 나오는 원소 인덱스를 리턴한다.
  • printAll() - 배열 리스트의 모든 원소를 리턴한다.

 

1) 인터페이스

public interface ListInterface<E>{
	
	public void add(int i, E x); 
	
	public void append (E x); 
	
	public void remove (int i); 
	
	public void removeItem (E x);
	
	public E get(int i); 
	
	public void set(int i, E x); 
	
	public int len(); 
	
	public boolean isEmpty(); 
	
	public void clear();
	
	public int IndexOf (E x); 
    
	public void printAll ();
	
}

 

2) 클래스

- 필드 영역

//필드 영역
	private E item[];
	private int size;
	private static final int DEFAULT_CAPACITY = 64;
  • item[] - 원소를 입력 받을 배열 리스트이다.
  • size - 원소의 개수를 저장할 정수형 변수이다.
  • DEFAULT_CAPACITY - 배열 리스트에 용량을 따로 선언하지 않을 경우 설정할 기본 용량이다.

 

- 생성자 영역

//생성자 영역
	public ArrayList() {
		item = (E[]) new Object [DEFAULT_CAPACITY];
		size=0;
	}
	
	public ArrayList(int n) {
		item = (E[]) new Object [n];
		size=0;
	}

 

 

- 메서드 영역

<add 메서드 구현>

@Override
	public void add(int i, E x) {
		if (size>=item.length||i<0|| i>item.length) throw new IllegalArgumentException();
		for (int j=size-1; j>=i; i--) {
			item[j+1]=item[j];
		}
		item[i]=x;
		size++;
	}
  • 예외처리 - 입력받은 인덱스가 범위를 벗어나는 경우, 배열 리스트에 빈 자리가 없을 경우
  • for문이 배열 리스트의 마지막 원소부터 i번째 인덱스의 원소까지의 모든 원소들을 뒤로 한 칸씩 밀어낸다.
  • 빈 공간이 된 i번째 인덱스에 원소 x를 입력한다.
  • size 변수를 1 증가시킨다.

<append 메서드 구현>

@Override
	public void append(E x) {
		if (size>=item.length) throw new IllegalArgumentException();
		item[size]=x;
		size++;
	}
  • 예외처리 - 배열 리스트에 빈 자리가 없을 경우
  • 배열 리스트의 끝에 원소 x를 입력한다.
  • size 변수를 1 증가시킨다.

<remove 메서드 구현>

@Override
	public void remove(int i) {
		if (size==0||i>size-1||i<0) throw new IllegalArgumentException();
		for (int j=i; j<size-1; j++) {
			item[j]=item[j+1];
		}
		item[size-1]=null;
		size--;
	}
  • 예외처리 - 입력받은 인덱스가 범위를 벗어나는 경우, 배열 리스트가 비어 있을 경우
  • for문이 입력받은 인덱스부터 마지막 원소의 이전 원소까지 순회하며 해당 원소의 다음 원소로 덮어쓴다.
  • for문 종료 후 마지막 원소를 null 처리해준다.
  • size 변수를 1 감소시킨다.

<removeItem 메서드 구현>

	@Override
	public void removeItem(E x) {
		int idx=-1;
		for (int i=0; i<size; i++) {
			if (item[i].equals(x)) {
				idx=i;
				break;
			}
		}
		
		for (int i=idx; i<size-1; i++) {
			item[i]=item[i+1];
		}
		item[size-1]=null;
		size--;
		
	}
  • 첫 번째 for문은 배열 리스트의 전체 인덱스를 순회하며 해당 인덱스의 원소가 x와 일치하는지 검사한다.
  • x와 일치하는 원소가 존재하면 해당 인덱스를 변수 idx에 저장하고 for문을 빠져나온다.
  • 두 번째 for문은 idx부터 마지막 원소의 이전 원소까지 순회하며 해당 원소의 다음 원소로 덮어쓴다.
  • for문 종료 후 마지막 원소를 null 처리해준다.
  • size 변수를 1 감소시킨다.
  • 만약 x와 일치하는 원소가 없다면 idx 변수에 -1 이 저장되어 있을 것이므로 인덱스 에러가 발생할 것이다.

<get, set, len, isEmpty 메서드 구현>

	@Override
	public E get(int i) {
		if (i<0||i>size-1||size==0) throw new IllegalArgumentException();
		return item[i];
	}

	@Override
	public void set(int i, E x) {
		if (i<0||i>size-1) throw new IllegalArgumentException();
		item[i]=x;
		
	}

	@Override
	public int len() {
		return size;
	}

	@Override
	public boolean isEmpty() {
		return (size==0);
	}
  • get - 입력받은 인덱스에 해당하는 값을 리턴한다.
  • 예외처리 - 입력받은 인덱스가 범위를 벗어나는 경우, 배열 리스트가 비어있을 경우
  • set - 입력받은 인덱스에 해당하는 값을 입력받은 값으로 교체한다.
  • 예외처리 -  입력받은 인덱스가 범위를 벗어나는 경우
  • size 변수를 리턴한다.
  • size==0 여부를 리턴한다.

<clear 메서드 구현>

	@Override
	public void clear() {
		item = (E[]) new Object [item.length];
		size=0;
		
	}
  • item 리스트를 기존 길이의 빈 배열 리스트로 덮어쓴다.
  • size 변수를 초기화한다.

<indexOf 메서드 구현>

	@Override
	public int IndexOf(E x) {
		int idx=-1;
		for (int i=0; i<size; i++) {
			if (item[i].equals(x)) {
				idx=i;
				break;
			}
		}
		
		return idx;
	}
  • for문이 배열 리스트의 전체 인덱스를 순회하며 해당 인덱스의 원소가 x와 일치하는지 검사한다.
  • x와 일치하는 원소가 존재하면 해당 인덱스를 변수 idx에 저장하고 for문을 빠져나온다.
  • 만약 x와 일치하는 원소가 없다면 idx 변수에 -1 이 저장되어 있을 것이므로 -1을 리턴한다.

<printAll 메서드 구현>

	@Override
	public void printAll() {
		for (int i=0; i<size; i++) {
			System.out.print(item[i]+" ");
		}
		System.out.println();
		
	}
  • for문이 전체 배열 리스트의 인덱스를 순회하며 해당 인덱스의 값들을 프린트한다.

-전체 코드

public class ArrayList<E> implements ListInterface<E> {
	
	//필드 영역
	private E item[];
	private int size;
	private static final int DEFAULT_CAPACITY = 64;
	
	//생성자 영역
	public ArrayList() {
		item = (E[]) new Object [DEFAULT_CAPACITY];
		size=0;
	}
	
	public ArrayList(int n) {
		item = (E[]) new Object [n];
		size=0;
	}
	
	//메서드 영역
	
	@Override
	public void add(int i, E x) {
		if (size>=item.length||i<0|| i>item.length) throw new IllegalArgumentException();
		for (int j=size-1; j>=i; i--) {
			item[j+1]=item[j];
		}
		item[i]=x;
		size++;
	}

	@Override
	public void append(E x) {
		if (size>=item.length) throw new IllegalArgumentException();
		item[size]=x;
		size++;
	}

	@Override
	public void remove(int i) {
		if (size==0||i>size-1||i<0) throw new IllegalArgumentException();
		for (int j=i; j<size-1; j++) {
			item[j]=item[j+1];
		}
		item[size-1]=null;
		size--;
	}

	@Override
	public void removeItem(E x) {
		
		int idx=-1;
		for (int i=0; i<size; i++) {
			if (item[i].equals(x)) {
				idx=i;
				break;
			}
		}
		
		for (int i=idx; i<size-1; i++) {
			item[i]=item[i+1];
		}
		item[size-1]=null;
		size--;
		
	}

	@Override
	public E get(int i) {
		if (i<0||i>size-1||size==0) throw new IllegalArgumentException();
		return item[i];
	}

	@Override
	public void set(int i, E x) {
		if (i<0||i>size-1) throw new IllegalArgumentException();
		item[i]=x;
		
	}

	@Override
	public int len() {
		return size;
	}

	@Override
	public boolean isEmpty() {
		return (size==0);
	}

	@Override
	public void clear() {
		item = (E[]) new Object [item.length];
		size=0;
		
	}

	@Override
	public int IndexOf(E x) {
		int idx=-1;
		for (int i=0; i<size; i++) {
			if (item[i].equals(x)) {
				idx=i;
				break;
			}
		}
		
		return idx;
	}


	@Override
	public void printAll() {
		for (int i=0; i<size; i++) {
			System.out.print(item[i]+" ");
		}
		System.out.println();
		
	}

}

 

3) 결과 확인하기

<코드>

public class Test {
	public static void main(String[] args) {
	
		ArrayList<Integer> lst = new ArrayList<>();
		
		lst.add(0, 100);
		
		lst.add(1, 200);
		
		lst.add(2, 300);
		
		lst.append(400);
		
		lst.printAll();
		
		//100,200,300,400을 차례로 입력하고 출력합니다.
		
		lst.remove(0);
		
		lst.printAll();
		
		lst.removeItem(400);
		
		lst.printAll();
		
		//0번째 인덱스의 값과 내용물이 400인 값을 삭제하고 출력합니다.
		
		lst.IndexOf(300);
		
		//300의 인덱스를 출력합니다.
		
		System.out.println(lst.isEmpty());
		System.out.println(lst.len());
		
		//lst가 비었는지 여부와 lst의 길이를 출력합니다.
		
		System.out.println(lst.get(0));
		
		//인덱스 0의 값을 출력합니다.
		
		lst.set(0, 1000);
		
		lst.printAll();
		
		//인덱스 0의 값을 1000으로 바꾸고 출력합니다.
		
		
	}
}

<결과>

정상적으로 출력된다.

+ Recent posts