본문 바로가기
Language/Java

컬렉션 프레임워크 1

by Zayne 2023. 2. 20.

■ 컬렉션 프레임워크 구조

 

 

■ 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