Be ready to study forever - 개발자 꿈나무
[JAVA 문법]Collection Framework - Lists 본문
컬렉션 프레임워크
컬렉션은 여러 개의 데이터그룹을 의미하면 프레임워크는 표준화된 프로그래밍 방식을 의미한다. 따라서, 컬렉션 프레임워크란 데이터의 집합을 표준화된 방식으로 프로그래밍을 할 수 있게 도와주는 방식으로 jdk 1.2부터 지원됨
1. 컬렉션 프레임워크 핵심 인터페이스
컬렉션 데이터는 크게 3가지의 그룹으로 나뉜다. List, Set, Map
List와 Set은 공통되는 부분이 있어 Collection인터페이스를 상속받지만 Map은 그렇지 않다. 아래의 표를 보면 좀더 정확한 상속 구조를 알 수 있다.
1.1 컬렉션 프레임워크 인터페이스 메서드
1.2. List 인터페이스 메서드
1.3. Set 인터페이스 메서드
1.4. Map 인터페이스 메서드
2. ArrayList
List인터페스이를 상속받아서 순서가 존재하고 중복을 허용한다. Vector와 기능, 구현원리가 동일하지만 Vector는 기존 소스와 호환성을 위해 존재하기 때문에 Vector보다는 ArrayList를 사용할 것을 권장한다.
ArrayList장점: 배열구조가 간단해서 데이터 접근에 속도가 빠르다.
ArrayList단점: 배열사이즈가 정해져 있다, 내부적으로는 배열사이즈를 늘릴 수 있지만 속도가 느려지는 담점이 있으며 순서 중간에 데이터를 삽입/삭제가 시간이 걸린다. 하지만, 마지막 순서의 데이터 삭제 및 추가는 빠르다. (따라서 Stack은 ArrayList로 구현하는 것이 적합하고, Queue는 ArrayList대신 LinkedList로 구현하는 것이 적합하다.)
2.1.ArrayList의 메서드
(1) 객체 생성 ArrayList<Integer> numbers = new Arraylist<>();
(2) 데이터 추가시 add 메소드 사용 numbers.add(10) numbers.add(1,50) : index 1번에 50이라는 숫자 넣기
(3)데이터 삭제시 remove 메소드 사용 numbers.remove(2) : index 2번째 값 삭제, 빈공간은 메꿈
(4) 데이터 가져올 때 get 메소드 사용 numbers.get(2) : index 2번째 값 가져오기
(5) 몇개 데이터 있는 지 확인 : size 메소드 사용 numbers.size();
(6) 반복(Iteration) Iterator it = numbers.iterator(); (아래 참고 바람) iterator 메소드 호출하여 Iterator 데이터 타입에 넣음 (iterator는 자바의 인터페이스)
|
2.2. Vector의 size와 capacity
2.3. ArrayList의 remove(int index) – ArrayList의 삭제시 내부적 동작 방법
특정 인덱스의 데이터를 삭제할 경우 ArrayList는 해당 인덱스 이후의 모든 데이터를 복사해서 해당인덱스에 덮어씌우기 하는 방식으로 지정된 인덱스를 삭제하게 된다. 이는 상당히 시간이 걸리는 일이므로 이러한 이유로 ArrayList는 특정한 인덱스를 지우거나 제일 앞에 있는 인덱스를 지우는 queue사용에 적합하지 않다.
3. LinkedList
위에서 언급했듯이 배열의 단점은 명확하다
1. 배열 크기에 대해 제약을 받으며 배열을 늘릴시에 성능저하의 문제가 있다.
2. 숫차적 데이터 접은에는 빠르나 비순차적 데이터(예를들면 데이터 중간에 삽입/삭제)에는 속도가 느리다.
이러한 단점을 보완하기 위하여 LinkedList라는 자료구조가 고안되었다.
LinkedList는 ArrayList와는 달리 불연속적인 데이터들을 주소 값으로 연결한 것으로. 주소 하나만 참조하는 ArrayList에비해 순차적 데이터 접근에는 느리지만, 중간에 데이터 삽입/삭제에는 더 효율적이다.
ArrayList의 참조방식
LinkedList의 참조방식
3.1.LinkedList의 이중연결 리스트
LinkedList는 이동방향이 단방향이기 때문에 이전데이터로의 접근이 어렵다 (2번째에서 3번째 데이터로 이동은 가능하지만, 3번째에서 2번째 데이터로 역방향 접근이 불가능.) 이를 보완하기 위해위해 나온 것이 이중연결 리스트(Doubly LinkedList)이다. 그리고, 보다 접근성을 더 보완하기 위해서 고안된 방법이 이중 원형 연결리스트(Doubly Circular LinkedList)이다. 도표를 보면 쉽게 이해가 가능하다.
3.2. LinkedList와 ArrayList의 성능비교
위에 언급한 바와 같이 ArrayList는 메모리에 순서대로 저장이 되기 때문에 순차적으로 저장되어 첫번째 주소 값만 참조하며 순차적인 데이터 접근에는 빠르지만, LinkedList는 모든 데이터를 일일이 차례대로 따라가야 하므로 순차적 접근에는 느리다. 하지만 데이터 추가 삭제에는 LinkedList가 훨씬 빠르다. 따라서 데이터 용량이 많고 변경이 거의 없다면 ArrayList를, 용량이 적고 변경이 많다면 LinkedList를 쓰는 것이 적절하다.
4. Queue 와 Stack
Queue는 FIFO(First In First Out), Stack은 LIFO(Last In First Out)이다. 앞서 언급했듯이, Queue는 ArrayList보다 LinkedList로 구현하는 것이 적합하며, Stack은 ArrayList로 구현하는 것이 적합하다.
일상생활에서 콜센터 대기열과 같은 것이 Queue이고 브라우저의 이전페이지, 다음페이지가 Stack과 같은 개념이다.
4.1 Stack메서드
메소드 |
설명 |
boolean empty() |
해당 스택이 비어 있으면 true를, 비어 있지 않으면 false를 반환함. |
E peek() |
해당 스택의 제일 상단에 있는(제일 마지막으로 저장된) 요소를 반환함. |
E pop() |
해당 스택의 제일 상단에 있는(제일 마지막으로 저장된) 요소를 반환하고, 해당 요소를 스택에서 제거함. |
E push(E item) |
해당 스택의 제일 상단에 전달된 요소를 삽입함. |
int search(Object o) |
해당 스택에서 전달된 객체가 존재하는 위치의 인덱스를 반환함. 이때 인덱스는 제일 상단에 있는(제일 마지막으로 저장된) 요소의 위치부터 0이 아닌 1부터 시작함. |
4.2. Queue메서드
메소드 |
설명 |
boolean add(E e) |
해당 큐의 맨 뒤에 전달된 요소를 삽입함. 만약 삽입에 성공하면 true를 반환하고, 큐에 여유 공간이 없어 삽입에 실패하면 IllegalStateException을 발생시킴. |
E element() |
해당 큐의 맨 앞에 있는(제일 먼저 저장된) 요소를 반환함. |
boolean offer(E e) |
해당 큐의 맨 뒤에 전달된 요소를 삽입함. |
E peek() |
해당 큐의 맨 앞에 있는(제일 먼저 저장된) 요소를 반환함. 만약 큐가 비어있으면 null을 반환함. |
E poll() |
해당 큐의 맨 앞에 있는(제일 먼저 저장된) 요소를 반환하고, 해당 요소를 큐에서 제거함. 만약 큐가 비어있으면 null을 반환함. |
E remove() |
해당 큐의 맨 앞에 있는(제일 먼저 저장된) 요소를 제거함. |
4.3. Deque(덱), Priority Queue
4.3.1 Deque
Deque는 단방향 추가/삭제가 아닌 양방향에서 데이터 핸드링이 가능하다. Queue를 상속받고, 구현체로는 ArrayDequeue, LinkedList등이 있다.
Deque 메서드
Deque |
Queue |
Stack |
offerLast() |
offer() |
push() |
pollLast() |
X |
pop() |
pollFirst() |
poll() |
X |
peekFirst() |
peek() |
|
peekLast() |
|
peek() |
4.3.2. PriorityQueue
Queue인터페이스 구현체중 하나로서 저장한 순서와는 상관없이 우선순위가 높은 것부터 꺼내게 된다는 특징이 있다. Null은 저장할 수 없고, Null이 저장될 경우 NullPointException이 발생한다.
5. Iterator, ListIterator, Enumeration
Iterator는 저장된 컬렉션에 요소들을 하나하나 접근해서 읽어 오기 위해서 사용되는 인터페이스이다. Enumberation은 Iterator의 구버전과 같은 인터페이스이며 소스 호환을 위해서 남겨진 것이기 때문에 Iterator를 쓰는 것이 좋다. ListIterator는 Iterator의 단점을 보완하기 위해서 나온 것인 데 Iterator는 단방향밖에 되지 않지만 ListIterator는 역방향으로 접근도 가능하게 되어있다.
예제코드
5.1. Iterator의 메서드
5.2. ListIterator 메서드
6. Arrays 클래스
Arrays클래스는 배열들 다루는데 유용한 메서드들이 있다. Arrays클래스의 모든 메서드들은 static클래스이므로 인스턴스 선언이 필요하지 않다.
6.1.Arrays의 주요 메서드
7. Comparable 과 Comparator
객체를 정렬하는데 필요한 기준을 제공한다.
Arrays.sort를 하면 내부적으로 Character클래스의 Comparable의 구현에 의해 정렬되는 것이다.
예제코드
import java.util.*;
class ComparatorEx {
public static void main(String[] args) {
String[] strArr = {"cat", "Dog", "lion", "tiger"};
Arrays.sort(strArr); // String의 Comparable구현에 의한 정렬
System.out.println("strArr=" + Arrays.toString(strArr));
Arrays.sort(strArr, String.CASE_INSENSITIVE_ORDER); // 대소문자 구분안함
System.out.println("strArr=" + Arrays.toString(strArr));
Arrays.sort(strArr, new Descending()); // 역순 정렬
System.out.println("strArr=" + Arrays.toString(strArr));
}
}
class Descending implements Comparator {
public int compare(Object o1, Object o2){
if( o1 instanceof Comparable && o2 instanceof Comparable) {
Comparable c1 = (Comparable)o1;
Comparable c2 = (Comparable)o2;
return c1.compareTo(c2) * -1 ; // -1을 곱해서 기본 정렬방식의 역으로 변경한다.
// 또는 c2.compareTo(c1)와 같이 순서를 바꿔도 된다.
}
return -1;
}
}
'Programming > JAVA' 카테고리의 다른 글
[JAVA 문법] Collection Framework - Map (0) | 2020.07.28 |
---|---|
[JAVA 문법] Collection Framework - Set (0) | 2020.07.28 |
[JAVA 문법] java.lang패키지 - Math클래스, Wrapper클래스 (0) | 2020.07.25 |
[JAVA 문법] java.lang패키지 - StringBuffer클래스 와 StringBuilder클래스 (0) | 2020.07.25 |
[JAVA 문법] java.lang패키지 - String 클래스 (0) | 2020.07.25 |