■ 컬렉션 프레임워크 구조
■ List<E> 인터페이스를 구현하는 컬렉션 클래스
List<E> 인터페이스를 구현하는 대표적인 컬렉션 클래스 둘은 다음과 같다
1) ArrayList<E> : 배열 기반 자료구조, 배열을 이용하여 인스턴스 저장
2) LinkedList<E> : 리스트 기반 자료구조, 리스트를 구성하여 인스턴스 저장
List<E> 인터페이스를 구현하는 컬렉션 클래스들의 공통적인 특징
1) 인스턴스의 저장 순서를 유지
2) 동일한 인스턴스의 중복 저장을 허용
ArrayList<E> 클래스의 사용 예시
import java.util.ArrayList;
import java.util.List;
public class ArrayListCollection {
public static void main(String[] args) {
List<String> list = new ArrayList<>();
list.add("Toy");
list.add("Box");
list.add("Robot");
for (int i = 0; i < list.size(); i++) {
System.out.print(list.get(i) + '\t');
System.out.println();
}
list.remove(0);
for (int i = 0; i < list.size(); i++) {
System.out.print(list.get(i) + '\t');
System.out.println();
}
}
}
LinkedList<E> 클래스의 인스턴스 생성은 다음 문장의 변화가 전부이다.
List<String> list = new ArrayList<>();
→ List<String> list = new LinkedList<>();
■ ArrayList<E> vs LinkedList<E>
ArrayList<E> 의 단점
1) 저장 공간을 늘리는 과정에서 시간이 비교적 많이 소요된다.
2) 인스턴스의 삭제 과정에서 많은 연산이 필요할 수 있다.
ArrayList<E> 의 장점
1) 저장된 인스턴스의 참조가 빠르다.
LinkedList<E> 의 단점
1) 저장된 인스턴스의 참조 과정이 배열에 비해 복잡하다.
(중간에 위치한 인스턴스를 참조하려면 맨 앞 또는 맨 뒤에서부터 한 칸씩 건너가야 하는 구조)
LinkedList<E> 의 장점
1) 저장 공간을 늘리는 과정이 간단하다.
2) 저장된 인스턴스의 삭제 과정이 단순하다.
■ 저장된 인스턴스의 순차적 접근 방법 : 반복자
List<String> list = new LinkedList<>();
Iterator<String> itr = list.iterator(); // 반복자 획득
Iterator<E> 에는 다음과 같은 메소드가 있다.
E next() // 다음 인스턴스의 참조 값을 반환
boolean hasNext() // next 메소드 호출 시 참조 값 반환 가능 여부 확인
void remove() // next 메소드 호출을 통해 반환했던 인스턴스 삭제
반복자를 이용한 순차적 참조
while(itr.hasNext()) {
str = itr.next();
}
반복자를 이용한 참조 과정 중 인스턴스의 삭제
while(itr.hasNext()) {
str = itr.next();
if(str.equals("Box")) {
itr.remove();
}
}
반복자는 생성과 동시에 첫 번째 인스턴스를 가리키고, next가 호출될 때마다 가리키는 대상이 다음 인스턴스로 옮겨진다.
이 반복자를 원하는 때에 다시 첫 번째 인스턴스를 가리키게 하려면 다시 반복자를 얻어야 한다.
컬렉션 인스턴스를 대상으로 for-each문을 작성하면 컴파일 과정에서 밑의 문장과 같이 수정되어 반복자에 의해 진행된다.
for (String s : list) {
System.out.print(s + '\t');
}
for (Iterator<String> itr = list.iterator(); itr.hasNext();) {
System.out.print(itr.next() + '\t');
}
■ 컬렉션 변환
List<String> list = Arrays.asList("Toy", "Robot", "Box");
// 인자로 전달된 인스턴스들을 저장한 컬렉션 인스턴스의 생성 및 반환
위 문장으로 생성된 컬렉션 인스턴스는 새로운 인스턴스의 추가나 삭제가 불가능하다.
그러나 다음 생성자를 기반으로 ArrayList<E> 인스턴스를 생성하면 가능하다.
class ArrayList<E> {
public ArrayList(Collection<? extends E> c) { ... } // 생성자
}
위 생성자를 분석해보면,
1) Collection<E> 를 구현한 컬렉션 인스턴스를 인자로 받을 수 있다.
2) E 는 인스턴스 생성 과정에서 결정되므로 무엇이든 될 수 있다.
3) 매개변수 c로 전달된 컬렉션 인스턴스에서는 참조만(꺼내기만) 가능하다.
List<String> list = Arrays.asList("Toy","Box","Robot","Box");
list = new ArrayList<>(list);
다음과 같이 ArrayList 인스턴스를 생성하면 인스턴스의 참조와 추가, 삭제가 가능하다.
■ 연결 리스트만 갖는 양방향 반복자
반복자를 통해서 한 쪽 방향으로만 호출이 가능했으나, List<E> 를 구현하는 클래스의 인스턴스들은
다음 메소드 호출을 통해 양방향 반복자를 얻을 수 있다.
public ListIterator<E> listIterator()
// ListIterator<E> 는 Iterator<E> 를 상속한다.
List<String> list = Arrays.asList("Toy","Box","Robot","Box");
list = new ArrayList<>(list);
ListIterator<String> litr = list.listIterator();
위와 같이 양방향 반복자를 얻으면 다음 메소드를 통하여 인스턴스의 참조 및 삭제가 가능하다
E next() // 다음 인스턴스의 참조 값을 반환
boolean hasNext() // next 메소드 호출 시 참조 값 반환 가능 여부 확인
void remove() // next 메소드 호출을 통해 반환했던 인스턴스를 삭제
E previous() // next 메소드와 기능은 같고 방향만 반대
boolean hasPrevious() // hasNext 메소드와 기능은 같고 방향만 반대
void add(E e) // 인스턴스의 추가
void set(E e) // 인스턴스의 변경
■ Set<E> 인터페이스를 구현하는 컬렉션 클래스
Set<E> 인터페이스를 구현하는 제네릭 클래스의 특성 두 가지
1) 저장 순서가 유지되지 않는다.
2) 데이터의 중복 저장을 허용하지 않는다.
Set<E>을 구현한 HashSet<E> 클래스의 사용 예시
Set<String> set = new HashSet<>();
'Language > Java' 카테고리의 다른 글
컬렉션 프레임워크 3 (0) | 2023.02.22 |
---|---|
컬렉션 프레임워크 2 (0) | 2023.02.21 |
제네릭 3 (0) | 2023.02.17 |
제네릭 2 (0) | 2023.02.16 |
제네릭 1 (0) | 2023.02.15 |