Dipa's document :: [JAVA] Collection Framework - List 컬렉션(ArrayList, Vector, LinkList)

오늘은 컬렉션 프레임워크 중에서 List 컬렉션에 대해서 알아보도록 하겠습니다.

List 컬렉션은 객체를 일렬로 늘어 놓은 구조로써, 객체를 인덱스로 관리를 하기 떄문에, 객체를 저장하면 자동으로 인덱스를 부여 하게 됩니다. 또한 리스트 컬렉션은 객체 자체를 저장하는 것이 아니라 객체의 참조 번지를 저장함으로써 힙영역에 객체를 가르키게 됩니다.

List 컬렉션의 특징으로는 앞서 컬렉션 프레임워크를 설명했을 때 처럼 순서를 유지하고 저장, 중복저장 가능하기 떄문에 같은 객체를 저장하게 되면 인덱스의 참조 번지는 같은 객체를 가르키게 되어 있고, null을 저장을 할 경우에는 인덱스에 있는 객체 참조 번지가 아무것도 가르키지 않게 됩니다.

* ArrayList

ArrayList 클레스에 객체를 저장을 하게 되면, 인덱스로 관리를 하게 됩니다. 일반 배열과 공통점은 인덱스로 관리한다는 점이지만, 배열과 ArrayList는 아주 큰 차이점이 있습니다.

바로 객체를 담을 크기가 유동적이라는 것입니다.!!

public class ArrayListExample {
   
	public static void main(String[] args) throws Exception {
		List<String> lists = new ArrayList<String>();
		
		
		//String 객체를 저장
		lists.add("java");
		lists.add("JDBC");
		lists.add("servlet/jsp");
		lists.add(2,"database");
		lists.add("ibaties");
		lists.set(4, "MyBatis");
		
		for(String list : lists){
			System.out.println(list.toString());
		}
		System.out.println();
		
		System.out.println("java라는 단어 있나요? " + lists.contains("java"));
		for(int i = 0; i<lists.size();i++){
			System.out.println(lists.get(i));
		}
		System.out.println();
		
		lists.remove(0);
		lists.remove("MyBatis");
		if(!lists.isEmpty()){
			lists.clear();
		}
		
		System.out.println("size : " + lists.size());
		
	}
}


ArrayList는 객체의 저장용량(capacity)을 default로는 10으로 설정이 되어 있다. 하지만 이 저장 용량을 초과하여 객체를 추가로 저장하게되면 자동적으로 값이 증가를 한다. 그렇다고 해서 다시 객체를 삭제를 한다고 해서 저장용량(capacity)이 줄어들지는 않는다.


public class ArrayListExample {
	 
    static int findCapacity(List<String> al) throws Exception {
        Field field = ArrayList.class.getDeclaredField("elementData");
        field.setAccessible(true);
        return ((Object[]) field.get(al)).length;
    }
   
	public static void main(String[] args) throws Exception {
		List<String> list = new ArrayList<String>();
		
		for(int i=0;i<100;i++){
			list.add(i+"");
			System.out.println("list_size : " + list.size() + ", list_ capacity : " + findCapacity(list));
		}
		
		System.out.println();
		
		for(int i=0;i<100;i++){
			list.remove(0);
			System.out.println("list_size : " + list.size() + ", list_ capacity : " + findCapacity(list));
		}
		
	}
}

* Vector

Vector클레스는 ArrayList 클레스의 구조와 비슷하지만 이 둘의 차이점은 멀티스레드의 환경에서 데이터를 처리를 하는지 입니다.. Vector클레스는 동기화된(synchronized)  메소드로 구성이 되어 있습니다. 따라서 멀티 스레드 환경에서 동시에 이 메소드를 접근을 할 수 없도록 구성 되어 있으며, 이를 스레드 안전 (Thread safe)라고 합니다


* LinkedList

linkedList 같은경우는 ArrayList와 사용 방법이 같습니다. 하지만 안의 내부구조가 다릅니다. ArrayList같은경우는 index에 의해서 관리가 되어 진다고 하면, LinkedList 같은경우는 인접해있는 노드를 연결해서 체인처럼 연결이 되어 있습니다. 따라서 중간의 데이터를 제거 하고싶다면 중간의 양쪽노드를 서로 이어주면 자동적으로 중간의 데이터는 없어지게 되는 것입니다.

예를 들어서 A->B->C 이렇게 연결이 되어 있을떄, B를 제거 하고싶으면 A에 연결되어있는 참조를 B가아닌 C로 이동을하여 A->C로 만들어주면 되겠죠? 


* ArrayList vs LinkedList

그렇다면 ArrayList와 LinkedList의 차이점은 무엇일까요? 둘은 쓰이는 곳이 다릅니다. 예를들어 수만개의 데이터가 있는데, 중간의 데이터를 추가하고 삭제하게되면 ArrayList값은 찾아서 데이터를 추가 삭제하고 그 다음칸에 있는 데이터는 한칸씩 뒤로 물러나게(index증가)됩니다. 그런데 이런 작업을 많이 하게되면 성능 저하의 원인이 되겠죠? 따라서 이런 작업이 많을 경우에는 LinkedList를 이용하는것이 좋습니다. 또한 검색/순차적으로 삭제&추가를 할 경우에는 ArrayList가 성능이 좋습니다.

정리 하자면, 

구분 

순차적으로 추가/삭제 

중간에 추가/삭제 

검색 

ArrayList 

빠르다

느리다 

빠르다 

 LinkedList

느리다 

빠르다 

느리다 



Posted by SH후니
,