컬렉션 프레임워크
일단 우리가 왜 컬렉션 프레임워크를 사용하는지 부터 알아야합니다.
우리가 프로그래밍을 하다가 보면 계속해서 사용하는 것이 바로 배열입니다.
이 배열은 여러 개의 객체를 저장하고 필요할 때 사용할 수 있도록 하는 방법 중 하나이며 가장 간단한 방법이라고 할 수 있습니다. 하지만 이 배열은 치명적인 단점이 있습니다.
바로 배열을 생성할 때 그 크기가 결정됩니다. 이렇게 되면 사용하지 않는 인덱스들이 생겨나게 되고 객체를 효율적으로 관리, 추가, 삭제, 검색을 할 수 없게 됩니다.
이 불편함을 없애고자 자바에서는 컬렉션 프레임워크를 제공해주고 있습니다.
위 그림은 어느 자바 책에 가면 다 있는 그림입니다.
주요 인터페이스로는 List / Set / Map 이 있습니다.
List / Set은 객체를 사용하는 방법이 비슷하고 공통점이 많기 때문에 공통된 메소드를 모아
Collection 인터페이스라고 정의해두고 있습니다.
Map은 Key와 Value값을 하나의 쌍으로 묶어서 관리하는 특징을 가지고 있습니다.
List 컬렉션
일단 List는 객체를 인덱스로 관리합니다. 객체를 저장하게 되면 배열과 다르게 자동으로 인덱스가 부여되고 그 인덱스를 이용하여 삽입하고 삭제하고 하면 됩니다. 또한 동일한 객체를 중복 저장할 수 있습니다.
또한, List 인터페이스를 구현하는 클래스로는 ArrayList / Vector / LinkedList가 있습니다.
1) ArrayList
배열과 아주 유사하지만 다른 점이 있다면 용량이 가변적입니다. 늘었다가 줄었다 합니다.
기본적으로 초기 용량이 10을 가지게 됩니다.
객체를 인덱스 0부터 차례대로 저장이되며, 중간에 객체를 제거할 경우 비어있지 않고 제거된 객체 뒤에 인덱스부터 끝까지 앞으로 1씩 당겨집니다. 알아서 빈 인덱스를 채워줍니다.
하지만 삽입을 하는 경우에는 조금 이야기가 다릅니다.
마지막 인덱스에 추가적으로 삽입을 하는 경우에는 간단하겠지만 중간 인덱스에 삽입을 하는 경우에는 비 효율적입니다.
<ArrayList 예제>
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 | package Collection; import java.util.ArrayList; import java.util.LinkedList; import java.util.Vector; public class List { public static void main(String[] args) { ArrayList<String> arrayList = new ArrayList<String>(); int size =0; arrayList.add("A"); // ArrayList와 같음 arrayList.add("B"); arrayList.add("C"); arrayList.add("D"); arrayList.add("E"); size = arrayList.size(); // ArrayList와 같음 System.out.println("arrayList size : " + size); String output = arrayList.get(0); // ArrayList와 같음 System.out.println("arrayList 0 : " + output); System.out.println("before remove : " + arrayList.toString()); arrayList.remove(0); System.out.println("after remove : " + arrayList.toString()); } } | cs |
2) Vector
Vector는 ArrayList와 동일한 내부 구조를 가지고 있습니다. 다른 점은 Vector는 동기화된 메소드로 구성이 되어 있습니다. 그래서 멀티 스레드 환경에서 안전하게 객체를 추가 / 삭제 / 할 수 있다는 장점이 있습니다.
<Vector 예제>
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 | package Collection; import java.util.ArrayList; import java.util.LinkedList; import java.util.Vector; public class List { public static void main(String[] args) { Vector<String> vector = new Vector<String>(); int size =0; vector.add("A"); // ArrayList와 같음 vector.add("B"); vector.add("C"); vector.add("D"); vector.add("E"); size = vector.size(); // ArrayList와 같음 System.out.println("arrayList size : " + size); String output = vector.get(0); // ArrayList와 같음 System.out.println("arrayList 0 : " + output); System.out.println("before remove : " + vector.toString()); vector.remove(0); System.out.println("after remove : " + vector.toString()); } } | cs |
3) LinkedList
LinkedList는 사용 방법은 ArrayList와 똑같지만 그 내부 구조는 완전히 다릅니다.
ArrayList는 인덱스로 객체를 관리했지만 LinkedList는 그와 다르게 위치 정보만 가지고 있으며 체인처럼 관리하고 있습니다. 그래서 중간에 객체를 추가 / 삭제 시에 그냥 밀어내거나 당길 필요가 없이 끊고 연결하면 됩니다
<LinkedList 예제>
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 | package Collection; import java.util.ArrayList; import java.util.LinkedList; import java.util.Vector; public class List { public static void main(String[] args) { LinkedList<String> linkedList = new LinkedList<String>(); int size =0; linkedList.add("A"); // ArrayList와 같음 linkedList.add("B"); linkedList.add("C"); linkedList.add("D"); linkedList.add("E"); size = linkedList.size(); // ArrayList와 같음 System.out.println("LinkedList size : " + size); String output = linkedList.get(0); // ArrayList와 같음 System.out.println("linkedList 0 : " + output); System.out.println("before remove : " + linkedList.toString()); linkedList.remove(0); System.out.println("after remove : " + linkedList.toString()); linkedList.add(2, "T"); // 객체 사이에 추가 System.out.println("between 1 and 3" + linkedList.toString()); } } | cs |
마지막으로 ArrayList와 LinkedList의 속도 비교를 해보겠습니다.
0번 인덱스에 객체를 1000번 추가 하는 동안 걸린 시간을 비교 해보겠습니다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 | package Collection; import java.util.ArrayList; import java.util.LinkedList; import java.util.Vector; public class List { public static void main(String[] args) { ArrayList<String> list1 = new ArrayList<String>(); LinkedList<String> list2 = new LinkedList<String>(); long startTime; long endTime; startTime = System.nanoTime(); for(int i=0; i<1000; i++) { list1.add(0, String.valueOf(i)); } endTime = System.nanoTime(); System.out.println("ArrayList 걸린시간 : "+(endTime - startTime) + "ns"); startTime = System.nanoTime(); for(int i=0;i<1000; i++) { list2.add(0,String.valueOf(i)); } endTime = System.nanoTime(); System.out.println("LinkedList 걸린시간 : "+ (endTime - startTime) + "ns"); } } | cs |
끝에서 부터 순차적으로 추가 / 삭제 하는 것은 ArrayList가 빠르지만,
중간에 추가 / 삭제 할 때는 LinkedList가 더 빠른 것을 알 수 있습니다.
각 자기가 구현하는 알고리즘에 맞게 사용하면 되겠습니다.
'Programming > Java' 카테고리의 다른 글
[기초] 자바 쉬운 프로젝트 #1 (1) | 2018.04.13 |
---|---|
[자바 기본] 컬렉션 프레임워크(List / Set / Map) Ⅲ (0) | 2017.08.22 |
[자바 기본] 스택과 큐(Stack and Queue) (0) | 2017.08.18 |
[자바 기본] 컬렉션 프레임워크(List / Set / Map) Ⅱ (0) | 2017.08.18 |
[디자인 패턴] Strategy Pattern (0) | 2017.06.02 |
댓글