Array와 List는 가장 기본적인 자료구조입니다.
Array는 일반적으로 배열이라고 부르는 자료구조입니다. 선언 및 사용에 있어 대괄호를 사용하며 제일 처음 저장되는 값은 0번째 자리에 저장되게 됩니다. 또한 처음 크기와 타입을 선언하게 되면 새로운 객체를 생성하기 전까지는 형태가 고정된다는 특징을 갖고 있습니다. 만일 배열크기를 넘어서게 되면 Exception이 나게 되며 처음 선언된 타입이 아닌 다른 타입의 자료형을 배열에 넣으려고 한다면 Type mismatch로 컴파일 자체가 안되게 됩니다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | import java.io.BufferedReader; import java.io.InputStreamReader; import java.util.StringTokenizer; public class ArrayTest { public static void main(String[] args) throws Exception { BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); StringTokenizer st = null; // 1 2 3 4 5 6 st = new StringTokenizer(br.readLine().trim()); int[] numbers = new int[5]; for (int i = 0; i < 6; i++) { numbers[i] = Integer.parseInt(st.nextToken()); } } } | cs |
배열은 다섯칸을 만들고 6개의 입력값을 넣어봤더니...
귀신같이 ArrayIndexOutOfBoundsException이 발생했습니다.
List는 그에 반해서 크기를 처음부터 정하지 않고 시작한다는 특징을 갖고 있습니다. 일단 객체를 선언하면 마치 쭉쭉 늘어나는 주머니 마냥 데이터를 저장할 수 있습니다. Array와 마찬가지로 선언된 type은 지켜줘야 하지만 크기와 상관없이 값을 저장할 수 있다는 측면에서는 매우 편리합니다. List에 무한정으로 값을 담을 수 있는 것은 아닙니다. 그렇게 하다가는 메모리가 터지는 것을 경험하실 수 있습니다.
그렇다면 어떤 때 Array를 사용하고 어떤 때 List를 사용해야할까요? 답은 없습니다. 저는 보통 입력될 값의 크기를 이미 파악하고 있고, 그 값 처리가 비교적 단순할 때, 그리고 테이블 모양의 이차원 배열을 사용해야할 때 Array를 이용합니다. 그에 반해서, 입력 크기가 비확정적일때 혹은 데이터 중간에 특정값의 위치 탐색이나 삭제 등 순서변형이 자주 일어나는 경우라면 List를 이용합니다. 그 이유는 List 클래스는 이러한 역할을 수행해줄 다수의 함수를 내포하고 있기 때문입니다. Array에서도 앞에서 말한 여러 작업처리가 가능하겠지만, 추가적인 기능이 한정적이어서 대부분의 기능을 사용자가 직접 구현해야합니다. 물론 구현이 자신있느 분이라면 무엇을 쓰셔도 상관없을 겁니다 ㅠ
Array와 List를 어떻게 사용하는지 하단의 소스를 통해 확인해보겠습니다.
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 | import java.io.BufferedReader; import java.io.InputStreamReader; import java.util.Arrays; import java.util.StringTokenizer; public class ArrayTest { public static void main(String[] args) throws Exception { BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); StringTokenizer st = null; st = new StringTokenizer(br.readLine().trim()); // Array의 선언 int[] numbers = new int[5]; // Array에 값을 저장합니다. 1 2 3 4 5 를 저장하겠습니다. for (int i = 0; i < 5; i++) { numbers[i] = Integer.parseInt(st.nextToken()); } // 제일 처음 저장된 값을 불러와서 프린트 해보겠습니다. System.out.println(numbers[0]); // Array의 크기는 length 함수를 이용하여 구할 수 있습니다. System.out.println(numbers.length); // Array는 clone을 이용하여 복사가 가능합니다. int[] cloneNumbers = numbers.clone(); // Array를 정렬하려면 확장된 기능을 위한 class인 Arrays를 이용해야합니다. Arrays.sort(numbers); } } | cs |
값의 저장과 불러오는 것은 매우 단순합니다. 'numbers[index값] = 입력값' 의 형식으로 저장이 가능하며, 'numbers[index값]'을 통하여 값을 읽어올 수 있습니다. 하지만 그러한 단순한 사용외에 다른 기능은 기대할 수 없습니다... 자료구조에서 가장 복잡한 문제인 정렬을 해결하기 위하여 확장된 기능을 위한 class인 Arrays를 제공합니다. 제일 마지막 라인을 보면 Arrays class의 sort 함수를 이용하여 배열을 자동 정렬한 것을 볼 수 있습니다. 정렬시 오름차순으로 정렬되며, 내림차순 정렬 혹은 이차원 배열 정렬 등은 Comparator를 이용하여 구현이 가능합니다.
List는 Array와 다르게 List class를 이용하여 구현하게 되어있습니다. List를 상속받아 구현된 List class 중 가장 대표적으로 사용되는 ArrayList class는 내부적으로 Array 구조를 갖고 있기 때문에 다른 리스트에 비하여 단순하고 빠르다는 장점이 있습니다. 사용측면에서도 Array와 유사한 기능적 특징을 갖고 있으며, 사용방법도 유사합니다.
두 자료구조는 유사하지만 분명한 차이점이 존재합니다.
첫째, List는 크기를 정하지 않고 선언되지만, Array는 처음 크기를 정하면서 선언됩니다.
Array의 특징을 갖고 있는 ArrayList는 내부적으로 Array를 갖고 있기 때문에, Array와 마찬가지로 처음에는 default 값으로 선언되게 됩니다. default 크기는 10입니다. 하지만 이는 내부적으로 선언된 크기에 불과하며 들어오는 데이터의 양이 늘어나게 되어 default 값을 넘어서게 될 경우 자동적으로 Array의 size를 증가시키기 때문에 사용자는 들어오는 값의 양이 얼마나 되는지 신경쓰지 않고 값을 저장시킬 수 있게 됩니다.
둘째, 처음 자료구조를 생성하는데 있어서도 차이가 있습니다.
Array는 프로그래밍 언어에서 기본적으로 제공되는 자료구조인만큼 class를 import 한다던가 하는 귀찮은 작업없이도 바로 선언하고 바로 사용이 가능합니다. 하지만 List는 Array 등을 이용하여 특별히 구현된 자료구조이기 때문에 ArrayList api를 import하여 객체를 생성하고, 이를 이용하여 값을 입력받고 사용하도록 되어있습니다.
셋째, Array는 기본 type을 저장할 수 있지만 List는 class만 type으로 사용할 수 있다.
Array는 int, long, float, double, boolean 등 기본적인 type으로 생성이 가능하며, String, Object class 등 기본적으로 주어지는 객체 및 사용자가 정의한 객체 등 특별히 type을 따지지 않고 생성이 가능합니다. 그에 반해 List는 앞에서 언급한 int, long, float, double, boolean 등 기본적인 type으로는 선언이 불가합니다. List에 이러한 기본 type의 자료를 저장하려면, 이 자료들을 객체화시킨 class로 저장해야합니다. Integer(int), Long(long), Float(float), Boolean(boolean) 등 객체 type으로만 List 선언이 가능하지만, 실제 사용할 때는 따로 객체화시켜줄 필요없이 바로 자료를 입력해도 됩니다. class 내부에 입력값을 객체화시켜주는 로직이 있기 때문입니다.
List의 선언 및 사용방법은 아래와 같습니다.
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 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 | import java.io.BufferedReader; import java.io.InputStreamReader; import java.util.ArrayList; import java.util.Collections; import java.util.StringTokenizer; public class ListTest { public static void main(String[] args) throws Exception { BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); StringTokenizer st = null; // list 객체는 처음 생성시에 Type을 설정해야 합니다. // 여기서는 Integer Type으로 생성되었습니다. ArrayList<Integer> list = new ArrayList<Integer>(); // list에 data를 저장할 때는 add 함수를 사용합니다. // Integer 객체로 저장해도 되지만, 그냥 저장해도 바로 타입전환되어 저장됩니다. list.add(new Integer(0)); list.add(2); list.add(5); list.add(9); list.add(11); // list에 저장된 값을 가져오려면 get 함수를 사용합니다. list.get(1); // list에 저장된 값이 몇 번째 index에 있는지 return해줍니다. // 값이 없으면 -1을 return합니다. list.indexOf(5); // 특정 index의 값을 삭제합니다. // 삭제된 index 뒤의 값이 하나씩 앞으로 이동합니다. list.remove(1); // 특정 값이 list에 존재하는지 확인합니다. // return은 값의 존재여부에 따라 true, false로 결정됩니다. list.contains(9); // list size를 return합니다. list.size(); // list에 하나라도 값이 존재하는지 확인합니다. // list가 비어있으면 true를 비어있지 않다면 false를 return 합니다. list.isEmpty(); // list는 Object Array로 변환할 수도 있습니다. Object[] array = list.toArray(); // list를 정렬할 때는 Collections class를 이용합니다. Collections.sort(list); // 이외에도 ArrayList는 다양한 기능을 제공하고 있으며, // Array에 비하여 그 기능이 훨씬 풍부합니다. // 하나씩 실습을 통해서 익혀놓으시면 나중에 문제풀이에 용이하게 사용하실 수 있습니다. } } | cs |
'Algorithm > Algorithm for Beginner' 카테고리의 다른 글
5. Stack과 Queue (2) | 2017.10.31 |
---|---|
4. Comparator를 이용한 Array와 List의 정렬 (2) | 2017.10.31 |
2. BufferedWriter와 System.out.println() 의 비교와 사용법 (0) | 2017.10.24 |
1. Scanner와 BufferedReader로 입력받기 (0) | 2017.10.17 |
0. 알고리즘 초보자를 위한 알고리즘 (0) | 2017.10.17 |