느림보 개발
컬렉션 프레임워크 - ArrayList 본문
컬렉션 프레임워크
데이터 군(=다수의 데이터)을 저장하는 클래스들을 표준화한 설계 를 뜻한다.
1.1 컬렉션 프레임워크의 핵심 인터페이스
컬렉션 프레임워크에서는 컬렉션데이터 그룹을 크게 3가지 타입이 존재한다고 인식하고 각 칼렉션을 다루는데 필요한 기능을 가진 3개의 인터페이스를 정의했다. List와 Set의 공통된 부분을 다시 뽑아서 새로운 인터페이스인 Collection을 추가로 정의했다. Map인터페이스는 이들과는 전혀 다른 형태로 컬렉션을 다루기 때문에 같은 상속계층도에 포함되지 못했다.
* 인터페이스? 객체 생성을 위한 설계도
다른 클래스를 작성할 때 기본이 되는 틀을 제공하면서, 다른 클래스 사이의 중간 매개 역할까지 담당하는 일종의 추상 클래스를 의미합니다. 다중 상속 지원
인터페이스 | 특징 |
List | 순서가 있는 데이터의 집합, 데이터의 중복을 허용한다. 예) 대기자 명단 구현 클래스 : ArrayList, LinkedList, Stack, Vector |
Set | 순서를 유지하지 않는 데이터의 집합, 데이터의 중복을 허용하지 않는다. 예) 양의 정수 집합, 소수의 집합 구현 클래스 : HashSet, TreeSet |
Map | 키와 값의 쌍으로 이루어진 데이터의 집합, 순서는 유지되지 않으며, 키는 중복허용하지 않고, 값은 중복 허용한다. 예) 우편번호, 지역번호(전화번호) 구현 클래스 : HashMap, TreeMap, HashTable, Properties |
key란, 데이터 집합 중에서 어떤 값을 찾는데 열쇠가 된다는 의미에서 붙여진 이름이다. 그래서 키(key)는 중복 허용하지 않는다.
1.2 ArrayList
컬렉션 프레임워크에서 가장 많이 사용되는 컬렉션 클래스일 것이다. ArrayList는 List인터페이스를 구현하기 때문에 데이터의 저장 순서가 유지되고 중복을 허용하는 특징을 갖는다. Vector를 개선한 것이다.
ArrayList는 Object 배열을 이용해서 데이터를 순차적으로 저장한다. 예를 들면, 첫 번째로 저장한 객체는 Object의 0번째 위치에 저장되고 그 다음에 저장하는 객체는 1번째 위치에 저장된다. 이런 식으로 계속 배열에 순서대로 저장되며, 배열에 더 이상 저장할 공간이 없으면 큰 새로운 배열을 생성해서 기존의 배열에 저장된 내용을 새로운 배열로 복사한 다음에 저장한다.
public class ArrayList extends AbstractList implements List, RandomAccess, Cloneable, java.io.Serializable {
...
transient Object[] elementData; // Object 배열
...
}
위 코드는 ArrayList의 소스코드 일부인데 ArrayList는 elementData라는 이름의 Objet배열을 멤버변수로 선언하고 있다는 것을 알 수 있다. 선언된 배열의 타입이 모든 객체의 최고 조상인 Object이기 때문에 모든 종류의 객체를 담을 수 있다.
예제
- list2의 각 요소에 접근하기 위해 get 메서드와 for문을 사용하였는데 for문의 변수 i를 0부터 증가시킨 것이 아니라 'list2.size()-1' 부터 감소시키면서 거꾸로 반복 시켰다.
- 만일 변수 i를 증가시켜가며 삭제하면 한 요소가 삭제할 때마다 빈 공간을 채우기 위해 나머지 요소들이 자리이동을 하기 때문에 올바른 결과를 얻을 수 없다.
package ch11;
import java.sql.Array;
import java.util.ArrayList;
import java.util.Collections;
public class ArrayListEx1 {
public static void main(String[] args) {
ArrayList list1 = new ArrayList(10);
list1.add(new Integer(5));
list1.add(new Integer(4));
list1.add(new Integer(2));
list1.add(new Integer(0));
list1.add(new Integer(1));
list1.add(new Integer(3));
ArrayList list2 = new ArrayList(list1.subList(1,4)); // 인덱스1부터 인덱스3까지!!!
// 4 2 0
System.out.println("list1 : "+list1+" ///// list2: "+list2);
Collections.sort(list1); //list1과 list2를 정렬한다.
Collections.sort(list2);
System.out.println("list1 : "+list1+" ///// list2: "+list2);
System.out.println("list1.containsAll(list2) : "+list1.containsAll(list2)); // true?
list2.add("B");
list2.add("C");
list2.add(3,"A");
System.out.println("list1 : "+list1+" ///// list2: "+list2); // 0 2 4 A B C
list2.set(3, "AA");
System.out.println("list1 : "+list1+" ///// list2: "+list2); // 0 2 4 AA B C
// list1에서 list2와 겹치는 부분만 나기고 나머지는 삭제
System.out.println("list1.retainAll(list2) : "+list1.retainAll(list2));
System.out.println("list1 : "+list1+" ///// list2: "+list2); // 0 2 4 , 0 2 4 AA B C
// list2에서 list1에 포함된 객체들을 삭제한다.
for (int i = list2.size()-1; i >= 0 ; i--) {
if(list1.contains(list2.get(i)))
list2.remove(i);
}
System.out.println("list1 : "+list1+" ///// list2: "+list2); // AA B C
} // main 끝
}
예제
- 긴 문자열 데이터를 원하는 길이로 잘라서 ArrayList에 담아 출력하는 예제이다.
- ArrayList를 생성할 때, 저장할 요소의 개수를 고려해서 실제 저장할 개수보다 약간 여유 있는 크기로 하는 것이 좋다. 생성할 때 지정한 크기보다 더 많은 객체를 저장하면 자동적으로 크기가 늘어나기는 처리시간이 많이 소요되기 때문이다.
package ch11;
import java.util.ArrayList;
import java.util.List;
public class ArrayListEx2 {
public static void main(String[] args) {
final int LIMIT = 10; // 자르고자 하는 글자의 개수를 지정한다. 4
String source = "0123456789abcdefghijABCDEFGHIJ!@#$%^&*()ZZZ";
int length = source.length();
List list = new ArrayList(length/LIMIT + 10); // 크기를 약간 여유 있게 잡는다.
for (int i = 0; i < length; i+=LIMIT) { // i = i+LIMIT
if(i+LIMIT < length){ // i+10 이 소스 길이보다 작을 때
list.add(source.substring(i,i+LIMIT)); // i부터 LIMIT까지 잘라 list에 추가
} else
list.add(source.substring(i)); // 인데스 i부터 뒤에 요소 모두 출력
}
for (int i = 0; i < list.size(); i++) {
System.out.println(list.get(i));
}
} // main()
}
예제
package ch11;
import java.util.Vector;
public class VectorEx1 {
public static void main(String[] args) {
Vector v = new Vector(5); // 용량이 5인 Vector를 생성한다.
v.add("1");
v.add("2");
v.add("3");
System.out.println(v);
System.out.println("size : "+v.size()); // 3
System.out.println("capacity : "+v.capacity()); // 5
v.trimToSize(); // 빈 공간을 없앤다. (용량과 크기가 같아진다)
System.out.println("====After trimToSize() ====");
System.out.println(v);
System.out.println("size : "+v.size()); // 3
System.out.println("capacity : "+v.capacity()); // 3
v.ensureCapacity(6);
System.out.println("====After ensureCapacity(6) ====");
System.out.println(v);
System.out.println("size : "+v.size()); // 3
System.out.println("capacity : "+v.capacity()); // 6
v.setSize(7);
System.out.println("====After setSize(7) ====");
System.out.println(v);
System.out.println("size : "+v.size()); // 7
System.out.println("capacity : "+v.capacity()); // 12 ==> 13이 아니라고?
v.clear();
System.out.println("====After clear() ====");
System.out.println(v);
System.out.println("size : "+v.size()); // 0
System.out.println("capacity : "+v.capacity()); // 12
}
public static void print(Vector v) {
System.out.println(v);
System.out.println("size : "+v.size());
System.out.println("capacity : "+v.capacity());
}
}
'기초' 카테고리의 다른 글
5. 404에러 not found (0) | 2023.02.22 |
---|---|
4. List, Map, Set (0) | 2023.02.17 |
3. html로 파라미터를 넘겨 javascript로 파라미터 받기 (0) | 2023.02.15 |
2. $(ducument).ready()와 $(window).onload() (0) | 2023.02.15 |
1. JSON (0) | 2023.02.11 |