목록성 데이터를 처리하는 자료구조를 의미.
java.util 패키지
에 컬렉션과 관련된 인터페이스와 클래스가 포함되어 있다.
컬렉션 인터페이스는 아래와 같이 선언된다.
컬렉션 인터페이스의 선언
public interface Collection<E> extends Iterable<E>
컬렉션(Collection) 인터페이스는 Iterable 인터페이스
를 확장(extends) 한다.
--> 즉 컬렉션 인터페이스는 Iterable 인터페이스를 사용해서 데이터를 순차적으로 가져올 수 있다.
컬렉션(Collection) 인터페이스를 확장한 인터페이스들은 크게 3가지로 분류된다.
1. List 인터페이스
: 순서가 있는 목록형
2. Set 인터페이스
: 순서가 중요하지않은 셋형
3. Queue 인터페이스
: 먼저 들어온것이 먼저나가는 큐형(FIFO)
이때 Map
은 별도의 인터페이스로 선언된다.
객체를 일렬로 늘어놓은 구조이다.
객체를 인덱스(index)
로 관리해서 객체를 저장하면 자동으로 인덱스가 부여되며 인덱스로 객체를 검색, 삭제할 수 있다. 즉 저장순서가 유지
된다.
객체 자체를 저장하는게 아니라 객체의 주소번지
를 참조한다.
동일한 객체를 중복 저장 가능
하다. 이때에는 동일한 주소번지가 참조된다.
null 값이 저장 가능하다. 이때 해당 인덱스는 객체의 주소번지를 참조하지 않는다.
ArrayList
List<E> list = new ArrayList<E>();
확장 가능한 배열이다. 데이터를 추가하면 인덱스(index)로 관리된다.
가장 상위부모는 Object 클래스이고 -> 그 다음 Abstract Collection -> 그 다음 AbstractList 순서로 확장된다.
Thread safe 하지않다. (synchroinzed 하지 않기 때문에 Vector보다 빠르다)
ArrayList에 객체를 추가하면 인덱스0 부터 차례대로 저장되며, 특정 인덱스가 제거된다면 바로 뒤 인덱스부터 마지막 인덱스까지 앞으로 1씩 당겨진다.
LinkedList
List<E> list = new LinkedList<E>();
List 인터페이스 및 Queue 인터페이스에 속한다.
ArrayList는 내부배열에 객체를 저장해서 인덱스로 관리하지만
LinkedList는 인접 참조를 링크해서 체인처럼 관리한다.
LinkedList에서 특정 인덱스의 객체를 제거하거나 추가할 때 앞뒤 링크만 변경되고 나머지 링크는 변경되지 않는다.
LinkedList와 ArrayList의 장단점
구분 | 순차적인 추가/삭제 | 중간에 추가/삭제 | 검색 |
---|---|---|---|
LinkedList | 느리다 | 빠르다 | 느리다 |
ArrayList | 빠르다 | 느리다 | 빠르다 |
Vector
List<E> list = new Vector<E>();
확장 가능한 배열이다. ArrayList와 동일한 내부구조를 갖는다.
ArrayList와는 다르게 Thread safe하다. (synchroinzed 제어자를 사용하여 해당 메서드나 클래스 단위에서 lock을 걸어서 multi thread 환경에서 안전성을 보장한다. 단 전체 요소를 빠르게 처리하지 못하므로 느리다.)
--> 즉 단일스레드 환경에서는 ArrayList를 사용하는것이 좋다.
Stack
: Vector 클래스를 확장해서 만든것. (LIFO 구조)
ArrayList
: 데이터 추가 가능 (동적), 단 읽을때 느리다. object element만 담을 수 있으며 동적인 길이를 갖는다.
Array(배열)
: 데이터 추가 불가능 (정적), 단 읽을때 빨라서 좋다. private type, object element를 담을 수 있는 길이가 고정되어 있으며, 사용중에 길이 변경 불가능하다.
리턴타입 | 메소드 이름 및 매개변수 | 정의 |
---|---|---|
boolean | add (E e) | 매개 변수로 넘어온 데이터를 배열의 가장 끝에 담는다. |
void | add (int index, E e) | 매개 변수로 넘어온 데이터를 지정된 index 위치에 담는다. |
boolean | addAll (Collection<? extends E> c) | 매개 변수로 넘어온 컬렉션 데이터를 가장 끝에 담는다. |
boolean | addAll (int index, Collection<? extends E> c) | 매개 변수로 넘어온 컬렉션 데이터를 index에 지정된 위치부터 담는다. |
public void ArrayTest1() {
ArrayList<String> list = new ArrayList<String>();
list.add("A");
list.add("B");
list.add("C");
list.add(1, "A2");
for(String x : list) {
System.out.println(x); // A, A2, B, C
}
}
index1 위치에 "A2"가 추가되었으므로 해당 위치에 있던 B부터 끝까지 index 위치가 1칸씩 뒤로 밀린다.
리턴타입 | 메소드 이름 및 매개변수 | 정의 |
---|---|---|
int | size( ) | ArrayList 객체에 들어가 있는 데이터의 개수를 리턴. |
E | get (int index) | 매개 변수에 지정한 위치에 있는 데이터를 관리. |
int | indexOf (Object o) | 매개 변수로 넘어온 자동 객체와 동일한 데이터의 위치를 리턴. |
int | lastIndexOf (Object o) | 매개 변수로 넘어온 객체와 동일한 마지막 데이터의 위치를 리턴. |
Object[ ] | toArray( ) | ArrayList 객체에 있는 값들을 Object[ ] 타입의 배열로 만든다. |
<T> T[ ] | toArray (T[ ] a) | ArrayList 객체에 있는 값들을 매개 변수로 넘어온 T타입의 배열로 만든다. |
배열(Array)과 문자열(String)의 길이를 가져올때는 .length( )
메서드 사용.
ArrayList 클래스는 들어있는 데이터의 개수를 확인하므로 .size( )
메서드 사용.
public void ArrayTest2() {
ArrayList<String> list = new ArrayList<String>();
list.add("A");
list.add("B");
list.add("C");
System.out.println(list.get(0)); // A
System.out.println(list.size()); // 3
System.out.println(list.indexOf("C")); // 2
System.out.println(list.lastIndexOf("C")); // 2
String[] strs = new String[0];
String[] listToArray = list.toArray(strs);
for(String x : listToArray) {
System.out.println(x); // A, B, C
}
String [] listToArray2 = list.toArray(new String[5]);
for(String x : listToArray2) {
System.out.println(x); // A, B, C, null, null
}
}
String[ ] 배열의 length < ArrayList의 size 일때 --> ArrayList의 size만큼 배열이 만들어진다.
String[ ] 배열의 length > ArrayList의 size 일때 --> 인자로 넘어가는 배열 객체의 length만큼 배열이 만들어진다.
(위 예시에는 ArrayList에 index 0~2까지 데이터가 담기고 index 3~4는 데이터가 없으므로 null로 출력된다.)
리턴타입 | 메소드 이름 및 매개변수 | 정의 |
---|---|---|
void | clear( ) | 모든 데이터 삭제 |
E | remove (int index) | 매개 변수에서 지정한 위치에 있는 데이터를 삭제하고, 삭제한 데이터를 리턴. |
boolean | remove (Object o) | 매개 변수에서 넘어온 객체와 동일한 첫번째 데이터를 삭제. |
boolean | removeAll (Collection<?> c) | 매개 변수로 넘어온 컬렉션 객체에 있는 데이터와 동일한 모든 데이터를 삭제. |
public void ArrayTest3() {
ArrayList<String> list = new ArrayList<String>();
list.add("A");
list.add("B");
list.add("C");
list.add("A");
list.clear();
for(int i=0; i<list.size(); i++) {
System.out.println("list.get("+i+")="+list.get(i));
// 아무것도 출력되지않음
}
}
public void ArrayTest3() {
ArrayList<String> list = new ArrayList<String>();
list.add("A");
list.add("B");
list.add("C");
list.add("A");
System.out.println(list.remove(0));
// A (삭제한 데이터 리턴)
for(int i=0; i<list.size(); i++) {
System.out.println("list.get("+i+")="+list.get(i));
// list.get(0)=B list.get(1)=C list.get(2)=A
}
}
public void ArrayTest3() {
ArrayList<String> list = new ArrayList<String>();
list.add("A");
list.add("B");
list.add("C");
list.add("A");
System.out.println(list.remove("A"));
// true
for(int i=0; i<list.size(); i++) {
System.out.println("list.get("+i+")="+list.get(i));
// list.get(0)=B list.get(1)=C list.get(2)=A
}
}
public void ArrayTest3() {
ArrayList<String> list = new ArrayList<String>();
list.add("A");
list.add("B");
list.add("C");
list.add("A");
ArrayList<String> temp = new ArrayList<>();
temp.add("A");
list.removeAll(temp);
for(int i=0; i<list.size(); i++) {
System.out.println("list.get("+i+")="+list.get(i));
// list.get(0)=B list.get(1)=C
}
}
출처
- 이지업 컨텐츠 내의 데어프로그래밍 자바강의
- 자바의 신 (책)
- 이것이 자바다 (책)