Chapter 14 - 1. Collection Framework - List
데이터의 저장, 그리고 이와 관련 있는 알고리즘을 구조화 해 놓은 프레임워크이다.
자료구조 알고리즘을 클래스로 구현해 놓은 것이다.컨테이너 클래스라고도 한다.모든 인터페이스가 제네릭으로 정의되어있다.
컬렉션 프레임워크 분류
자바의 컬렉션 프레임워크에서는 크게 3가지 타입이 존재한다고 인식하고 3개의 인터페이스를 정의하였다.
List < CollectionSet < CollectionMap
그리고, List와 Set의 공통부분을 다시 뽑아, Collection 이라는 인터페이스를 정의하였다.
List
| 동일한 인스턴스의 중복을 허용한다
| 인스턴스 저장 순서가 유지된다.
ex> ArrayList, LinkedList, Stack etc...
Set
| 데이터의 중복저장을 허용하지 않는다.
| 저장 순서를 유지 하지 않는다.
ex> HashSet, TreeSet etc...
Map
| 키와 값의 쌍으로 이루어진 데이터의 집합.
| 순서는 유지되지 않으며, 키는 중복을 허용하지 않고, 값은 중복을 허용한다.
ex> HashMap, TreeMap, Properties etc...
Collectioin 인터페이스와 List 인터페이스에서는,
자신을 상속하는 많은 컬렉션 프레임워크들이 공통적으로 유용하게 사용할 수 있는 각종 기본적인 메소드를 제공한다.
ArrayList < List
ArrayList는 기존 Java의 Vector를 개선한 것으로 구현원리와 기능적인 측면은 동일하다.
일단, 몇개의 배열을 사용할지 정하지 않아도 된다.
code>
1 2 3 4 5 6 7 | ArrayList al = new ArrayList(); al.add( "one"); //값 넣어주기, 자동으로 0부터 들어간다. al.add( "two"); al.add( "three"); for (int i =0 ; i<al.size(); i++){ //열거할 때, al.size() 를 이용 System.out.println(al.get(i)); } | cs |
조심해야할 부분, ArrayData에 추가한 데이터의 형식은 문자열
add는 어떠한 형태의 데이터 타입도 수용할 수 있다. 그래서 인자의 데이터 타입이 Object이다.
그래서 위의 "one"은 저장될 때 Object 타입으로 저장이 된다.
1 | String value = (String) al.get(i); | cs |
따라서, String 타입의 value 변수에 담으려면 (String) 을 통해 명시적 형변환을 해줘야 한다.
이건 선택이 아니고 필수다. 자신이 넣어준 데이터의 타입으로 형변환을 해줘야만 한다.
이것을 제네릭을 통해서 한다!
code>
1 2 3 4 5 6 7 8 | ArrayList <String> al = new ArrayList<String>(); al.add( "one"); //값 넣어주기, 자동으로 0부터 들어간다. al.add( "two"); al.add( "three"); for (int i =0 ; i<al.size(); i++){ //열거할 때, al.size() 를 이용 System.out.println(al.get(i)); } list.remove(0); // 첫번째 리스트 내역 삭제. 인스턴스의 참조값이 지워진다. | cs |
가장 많이 사용하는 컬렉션 프레임워크이다! BUT, 단점도 존재한다.
ArrayList<E> 단점
1. 저장소의 용량을 늘리는 과정에서 많은 시간이 소요된다.
용량을 늘린다는 것은 새로운 배열 인스턴스의 생성과 기존 데이터의 복사가 필요한 작업이다.
즉, 기존의 ArrayList에 추가하는 것이 아닌, 확장된 크기의 ArrayList를 새로 생성하고,
새로 생성된 ArrayList에 기존의 ArrayList의 값들을 복사해주는 과정인 것이다.( System.arraycopy( ) 메소드 호출 과정 )
기존의 ArrayList는 가비지 컬렉션에 의해 메모리에서 제거된다.
용량이 부족할 경우, ArrayList는 자동적으로 기존의 크기보다 2배의 크기로 증가한다.
2. 데이터의 삭제에 필요한 연산과정이 매우 길다.
Worst Case 로 첫번째 위치에 저장되어 있는 데이터를 지우고자 할 때를 보자.
모든 데이터가 한 칸씩 앞으로 당겨진다.
즉, 삭제하고자 하는 첫번째 값을 두번째 값이 덮어쓰고,
두번째 값은 세번째 값에 의해 덮어쓰이게 되는 것이다.
그리고나서 마지막 값을 null로 바꿔준다.
이 때도 역시, 덮어쓰는 과정에서 System.arraycopy( ) 메소드가 호출된다.
물론 배열의 맨 마지막의 값을 삭제하는 경우는 빠른 성능을 보인다.
ArrayList 장점으로는 인덱스 값만 알면 데이터에 바로 접근이 가능하다는 점이 있다.
즉, Index 값을 통한 Random Access가 가능한 것이다.
LinkedList < List
LinkedList는 ArrayList와 반대다.
저장소의 용량을 늘리는 과정이 간단하며(마지막 박스가 가리키는 것이 NULL이 아닌 박스로 바꿔주면 된다.)
데이터의 삭제가 매우 간단하다.(가리키는 박스의 종류만 다르게 해주면 된다.)
하지만 데이터의 참조가 다소 불편하다.
불연속적으로 위치한 각 요소들이 서로 연결된 것이라
처음부터 n번째 데이터까지 차례대로 따라가야만 원하는 값을 얻을 수 있다.
즉, 박스(Node)를 타고 이동하면서 하나씩 순차적으로 확인해줘야 한다.
이러한 문제점을 해결하기 위해 여러 기능들이 추가된 LinkedLIst가 존재한다.
Double LinkedList & Double Circular LinkedList
더블 링크드리스트는 참조하는 변수를 하나 더 생성하여,
다음 Node 뿐만 아니라, Previous Node, 즉 이전의 Node도 가리키게 하여,
양방향 접근이 가능하도록 개선한 LinkedList이다.
더블 써큘러 링크드 리스트는 여기서 한발짝 더 나아가,
마지막 Node가 첫번째 Node를 가리키게 하여,
각 Node에 대한 접근성을 높인 LinkedList이다.
위 포스팅 내용은 생활코딩의 이고잉님의 강의자료와 '자바의 정석'교재를 기준으로 작성하였습니다. 문제가 될 시 삭제하겠습니다.
Chapter 14-1. The End
'Dev.BackEnd > JAVA' 카테고리의 다른 글
[JAVA] 15. Thread ( 스레드 ) (0) | 2016.08.20 |
---|---|
#Reflection 리플렉션이란? (0) | 2016.07.19 |
[JAVA] 13. 열거형 Enum (0) | 2016.07.16 |
[JAVA] 12. Generics (지네릭스) (0) | 2016.07.16 |
[JAVA] 11 - 2. Object 클래스와 그 메소드들 (0) | 2016.07.16 |