어떤 동작은 ArrayList가 빠르거나 메모리를 덜 소모하고, 어떤 동작은 LinkedList가 더 높은 효율을 보일 떄가 있다.
JCF를 사용하다 보면 종종 ArrayList와 LinkedList를 혼동한다. 왜 자바는 List 인터페이스에 두 가지 구현을 제공할까? 어떤 것을 선택해야 할까? 이에 대해 알아보자.
자바의 interface는 메소드의 집합을 의미한다. interface를 구현하는 클래스는 interface에 명시된 메소드를 제공해야 한다. 예를 들어 java.lang 에 정의된 Comparable interface의 소스코드는 아래와 같다.
package java.lang;
import java.util.*;
public interface Comparable<T> {
public int compareTo(T o);
}
이 인터페이스는 다음과 같이 구현해야 한다.
이 Comparable interface를 구현하는 java.lang.Integer 클래스의 소스코드를 살펴보자.
package java.lang
import ...
public final class Integer extends Number implements Comparable<Integer> {
// 생략
public int compareTo(Integer anotherInteger) {
return compare(this.value, anotherInteger.value);
}
// 생략
public static int compare(int x, int y) {
return (x < y) ? -1 : ((x == y) ? 0 : 1);
}
// 생략
}
이 클래스는 Number 클래스를 상속받는다. Number 클래스의 메소드와 인스턴스 변수를 상속하고 Comparable<Integer> 인터페이스를 구현한다.
클라스가 interface를 구현한다고 선언하면 컴파일러는 interface가 정의한 모든 메소드를 제공하는지 확인한다.
JCF는 **ArrayList**와 **LinkedList**라는 두 가지 구현 클래스를 가진 List 인터페이스를 정의한다.
List 인터페이스는 List가 되기 위한 필수 요건들을 명시한다. 이를 구현한 클래스들은 add, get, remove 등과 같은 약 20여 가지 메소드를 제공해야 한다.
ArrayList와 LinkedList 클래스는 이러한 메소드들을 모두 구현하고 있기 때문에, 서로 교환하여 사용할 수 있다. List를 활용하는 메소드들은 ArrayList, LinkedList, 그리고 다른 List 인터페이스를 구현하는 모든 객체와도 잘 호환된다.
import java.util.LinkedList;
import java.util.List;
public class ListClientExample {
private List list;
public ListClientExample(){
list = new LinkedList();
}
public List getList(){
return list;
}
public static void main(String[] args) {
ListClientExample lce = new ListClientExample();
List list = lce.getList();
System.out.println("list = " + list);
}
}
실행 로그