코드일기장

[Java] ArrayList 본문

컴퓨터 과학/자료구조

[Java] ArrayList

won_hyeok2 2022. 3. 28. 14:59

 

 

  ArrayList는 컬렉션 프레임웍에서 가장 많이 사용되는 컬렉션 클래스일 것이다.

 

  ArrayList는 List인터페이스를 상속받은 클래스이다. List인터페이스로부터 상속받았기 때문에 데이터의 저장 순서가 있고 중복을 허용한다는 특징이 있다.

 

 

  ArrayList는 Vetor를 개선해서 만든 것으로 Vector와 구현원리와 기능적인 측면이 매우 흡사하다. 

 

  ArratyList는 Object배열을 이용해서 데이터를 순차적으로 저장한다. 흔히 사용하는 배열과 똑같다고 생각하면 된다. 예를 들어 Integer 5를 저장하면 Object배열 index0에 저장되고 다음 숫자는 index1...  이런 식으로 순서대로 쭉 저장된다.

 

 

  배열과 ArrayList의 차이점은 배열은 한번 크기를 지정하면 크기를 다시 수정을 못한다. 하지만, ArrayList는 크기가 가변적이다. 만약 현재 가용량(Capacity) 이상을 저장하려고 할 때 메모리를 새롭게 할당해 데이터를 또 저장할 수 있게 공간을 만든다.

 

 

  


 

🎈 ArrayList의 메서드

ArrayList 클래스를 사용할 때 주로 사용되는 메서드들을 정리해보았다.

 

<표 1> Java의 정석 남궁성 지음 ArrayList메서드 참조

메서드 설명
ArrayList () 크기가 0인 ArrayList를 생성한다.
ArrayList (Collection c) 주어진 컬렉션이 저장된 ArrayList를 생성한다.
ArrayList (int initialCapacity) 저장된 초기용량을 갖는 ArrayList를 생성한다.
boolean add (Object obj) ArrayList의 마지막에 객체를 추가. 성공하면 true
void add (int index, Object element) 지정된 위치(index)에 객체를 저장한다.
boolean addAll (Collection c) 주어진 컬렉션의 모든 객체를 저장한다.
boolean addAll (int index, Collection c) 지정된 위치부터 주어진 컬렉션의 모든 객체를 저장한다.
void clear() ArrayList를 완전히 비운다.
Object clone() ArrayList를 복제한다.
boolean contains (Object o) 지정된 객체(o)가 ArrayList에 포함되어 있는지 확인한다.
void ensureCapacity (int minCapactiy) ArrayList의 용량이 최소한 minCapacity가 되도록 한다.
Object get (int index) 지정된 위치(index)에 저장된 객체를 반환한다.
int indexOf (Object o) 지정된 객체가 저장된 위치를 찾아 반환한다.
boolean isEmpty() ArrayList가 비어있는지 확인한다.
Iterator iterator() ArrayList의 Iterator 객체를 반환한다.
int lastIndexOf (Object o) 객체 (o)가 저장된 위치를 끝부터 역방향으로 검색해서 반환한다.
Listlterator listlterator ArrayList의 Listlterator를 반환한다.
Listlterator listlterator (int index) ArrayList의 지정된 위치부터 시작하는 Listlterator를 반환한다.
Object remove (int index) 지정된 위치 (index)에 있는 객체를 제거한다.
boolean remove (Object o) 지정한 객체를 제거한다. (성공하면 true 실패하면 false)
boolean removeAll (Collection c) 지정한 컬렉션에 저장된 것과 동일한 객체들을 ArrayList에서 제거한다.
boolean retainAll (Collection c) ArrayList에 저장된 객체 중에서 주어진 컬렉션과 공통된 것 들만을 남기고 나머지는 삭제한다. (c와 공통되지 않은 요소들은 삭제)
Object set (int index, Object element) 주어진 객체(element)를 지정된 위치(index)에 저장한다.
int size() ArrayList에 저장된 객체의 개수를 반환한다.
void sort (Comparator c) 지정된 정렬기준 (c)으로 ArrayList를 정렬한다.
List subList (int fromIndex, int toIndex) fromIndex부터 toIndex사이에 저장된 객체를 반환한다.
Object[] toArray() ArrayList에 저장된 모든 객체들을 객체배열로 반환한다.
Object[] toArray (Object[] a) ArrayList에 저장된 모든 객체들을 객체배열 a에 담아 반환한다.
void trimToSize() 용량을 크기에 맞게 줄인다. (빈 공간을 삭제한다.)

 

 

 

 

 

 


 

 

예제 코드

import java.util.*;

public class ArrayListEx1 {

	public static void main(String[] args) {
		ArrayList<Integer> list1 = new ArrayList<Integer>(10);
		list1.add(new Integer(5));
		list1.add(new Integer(4));
		list1.add(2);
		list1.add(0);
		list1.add(1);
		
		ArrayList list2 = new ArrayList<>(list1.subList(1, 4));
		System.out.println("list1: "+list1);
		System.out.println("list2: "+list2);
		Collections.sort(list1); Collections.sort(list2);
		//정렬 후 ArrayList 출력
		System.out.println("list1: "+list1);
		System.out.println("list2: "+list2);
		
		System.out.println("list1.contains(list2): "+list1.containsAll(list2));
		
		list2.add("B");
		list2.add("C");
		list2.add(3,"A");
		System.out.println("list2: "+list2);
		list2.set(3, "AA"); //index3의 값을 "AA"로 변경
		System.out.println("list2: "+list2);
		
		list1.retainAll(list2); //list2랑 겹치는거 값 빼고 다 삭제
		System.out.println("list1: "+list1);  
		
		for(int i=list1.size()-1;i>=0;i--) {
			if(list1.contains(list2.get(i))) {
				list2.remove(i);
			}
		}
		System.out.println("list1: "+list1);
		System.out.println("list2: "+list2);
	}

}

 

list1: [5, 4, 2, 0, 1]
list2: [4, 2, 0]
list1: [0, 1, 2, 4, 5]
list2: [0, 2, 4]
list1.contains(list2): true
list2: [0, 2, 4, A, B, C]
list2: [0, 2, 4, AA, B, C]
list1: [0, 2, 4]
list1: [0, 2, 4]
list2: [AA, B, C]

 

 

ArrayList는 List 인터페이스를 구현했기 때문에 저장된 순서를 유지한다는 것을 알 수 있다.

 

 

 

 


 

 

ArrayList의 추가와 삭제

 

  ArrayList의 요소를 삭제하는 경우, 삭제할 객체의 바로 아래에 있는 데이터를 한 칸씩 위로 복사해서 삭제할 객체를 덮어쓰는 방식으로 처리한다. 만일 삭제할 객체가 마지막 데이터라면, 복사할 필요 없이 단순히 null로 변경해주기만 하면 된다. 

 

  아래 그림은 boolean remove(2) 메서드를 사용해 2를 없애는 그림이다.

  그림을 요약하면 

 

1. 삭제할 데이터의 아래에 있는 데이터를 한 칸씩 위로 복사해서 삭제할 데이터를 덮는다.

2. 데이터가 모두 한 칸씩 위로 이동하였으므로, 마지막 데이터는 null로 변경한다.

3. 데이터가 삭제되어 데이터의 개수 (size)가 줄었으므로 size의 값을 1 감소시킨다.

  

 

 

  ArrayList의 삭제는 매우 비효율적이다. 우리는 객체를 순차적으로 저장할 때와 객체를 마지막에 저장된 것부터 삭제하면 1번 과정을 생략할 수 있다. 배열의 중간에 있는 값을 삭제하기 위해서는 다른 데이터를 위치를 이동시켜 주고, 복사해야 하므로 시간이 오래 걸린다. 

 

 

 

 

 

  이처럼 배열의 마지막 요소를 삭제한다면 1번 과정이 생략되므로, 작업시간을 줄일 수 있다. 

 

 

 

 

for문으로 ArrayList 전체적으로 삭제할 때 효율적이게 삭제하는 방법

  앞에서 말했듯 ArrayList에서 객체를 삭제할 때 1번 과정을 생략하게 해야 한다.  이를 생각하고 반복문을 통해 ArrayList의 값들을 차례대로 삭제해보겠다.

 

 

import java.util.*;

public class ArrayListEx1 {

	public static void main(String[] args) {
		ArrayList<Integer> list1 = new ArrayList<Integer>(10);
		list1.add(1);
		list1.add(5);
		list1.add(8);
		list1.add(10);
		
		for(int i=list1.size()-1;i>=0;i--) {
			print(list1);
			list1.remove(i);
		}
		print(list1);
	}
	static void print(ArrayList list1) {
		System.out.println("list1: "+list1);
	}
}

 

이런 식으로 반복문 내에서 ArrayList의 객체의 마지막부터 삭제하면 작업시간이 훨씬 줄어들어 효율적인 프로그램을 만들 수 있다.

 

 

 

 

 

Comments