자료 구조란 IT학문 분야 중 하나입니다.
프로그램을 짜다보면 데이터가 많아지는데 어떻게 하면 효율적으로 관리할 수 있을지에 대한 구조의 연구예요.
자료 구조를 인터페이스 구조로 정리를 해놓는데, 그 구조의 집합을 컬렉션 프레임 워크라고 합니다.
즉, 컬렉션 프레임 워크는 자바에서 자료구조를 정의해 표준 인터페이스 형태로 제공하는 것입니다.
컬렉션 프레임 워크 골격에 해당하는 인터페이스들은 다음과 같습니다.
자료 구조 및 알고리즘을 구현해 놓은 일종의 라이브러리이고, 제네릭을 기반으로 구현이 되어 있습니다.
각 인터페이스를 하나씩 살펴볼게요.
1. Lise<E> 인터페이스
데이터를 일렬로 보관합니다. 마치 배열과도 같이요.
리스트에 대한 특징을 알아볼게요.
- 선형적인 자료구조입니다. (일렬로 데이터를 보관)
(선형적 구조 : 직선인 구조. 일렬의 구조.
비선형적 구조 : 직선 모양이 아닌 구조. )
- 데이터의 저장 순서를 유지합니다.
- 동일한 데이터도 두 번 이상 저장할 수 있습니다. (중복 저장 허용)
인터페이스로는 인스턴스가 생성 불가능하므로, 리스트는 인터페이스로 구성된 클래스를 제공합니다.
- ArrayList<E> 배열 기반 자료구조, 배열을 이용하여 인스턴스를 저장. (배열 리스트)
- LinkedList<E> 리스트 기반 자료구조, 리스트를 구성하여 인스턴스를 저장 (연결 기반 리스트, 동적인 리스트)
ArrayList<E>의 예제를 들어보겠습니다.
public static void main(String[] args) {
List<String> list = new ArrayList<>(); // 컬렉션 인스턴스 생성
//객체는 ArrayList 를 만들고, List 타입으로 사용한다.
// 컬렉션 인스턴스에 문자열 인스턴스 저장
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> 의 예제를 들어보겠습니다.
public static void main(String[] args) {
List<String> list = new LinkedList<>(); // 유일한 변화!!!
// 컬렉션 인스턴스에 문자열 인스턴스 저장
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();
}
리스트 기반 자료구조는 열차 칸을 더하고 빼는 형태의 자료구조입니다.
인스턴스 저장 → 열차 칸을 하나 더합니다.
인스턴스 삭제 → 해당 열차 칸을 삭제합니다.
데이터가 없으면 데이터 공간은 비어 있습니다.
데이터가 추가 될수록 할당이 되는 것으로 배열보다 메모리 효율이 좋을 수도 있습니다.
단, 동적 할당이므로 처리 속도가 느립니다.
ArrayList<E> | LinkedList<E> |
ArrayList<E>의 단점 - 저장 공간을 늘리는 과정에서 시간이 비교적 많이 소요됩니다. - 인스턴스의 삭제 과정에서 많은 연산이 필요할 수 있습니다. 따라서 느릴 수 있습니다. (배열 기반이므로 삭제를 하면 배열을 다시 정렬을 해야하기 때문) ArrayList<E>의 장점 - 저장된 인스턴스의 참조가 빠릅니다. |
LinkedList<E>의 단점 - 저장된 인스턴스의 참조 과정이 배열에 비해 복잡합니다. 따라서 느릴 수 있습니다. (배열처럼 인덱스 번호가 붙어있는 것이 아니므로 해당 데이터가 발견될 때까지 처음부터 반복문으로 따라가야 하기 때문) LinkedList<E>의 장점 - 저장 공간을 늘리는 과정이 간단합니다. - 저장된 인스턴스의 삭제 과정이 단순합니다. (연결이 끊어지면 그 다음 인스턴스로 이어집니다.) |
다음 예제를 한 번 더 확인해보겠습니다.
import java.util.List; // 자바 유틸 import
import java.util.LinkedList;
import java.util.Iterator;
class IteratorCollection {
public static void main(String[] args) {
List<String> list = new LinkedList<>(); // 리스트형 인터페이스 생성
// 인스턴스 저장
list.add("Toy"); list.add("Box");
list.add("Robot"); list.add("Box");
// 반복자 획득
Iterator<String> itr = list.iterator(); //Iterator 는 값을 가져오거나 삭제할 때 사용
// 반복자를 이용한 순차적 참조
while(itr.hasNext())
System.out.print(itr.next() + '\t');
System.out.println();
// 반복자 다시 획득 (처음부터 다시 읽을 수 있도록 반복자를 다시 읽음)
itr = list.iterator();
// "Box"의 삭제
String str;
while(itr.hasNext()) {
str = itr.next();
if(str.equals("Box"))
itr.remove();
}
// 반복자 다시 획득 (지워진 후의 결과를 확인할 수 있음)
itr = list.iterator();
// 삭제 후 결과 확인
while(itr.hasNext())
System.out.print(itr.next() + '\t');
System.out.println();
}
}
리스트만 가지고 있는 양방향 반복자가 있습니다.
즉, 앞에서 읽는 것과 뒤에서 읽는 것 둘 다 가능하다는 것입니다.
참조 정보가 양 방향에 있을 수 있습니다.
public ListIterator<E> listIterator() // List<E> 인터페이스의 메소드
→ ListIterator<E>는 Iterator<E>을 상속합니다.
E next() 다음 인스턴스의 참조 값을 반환 boolean hasNext() next 메소드 호출 시 참조 값 반환 가능 여부 확인 void remove() next 메소드 호출을 통해 반환했던 인스턴스를 삭제 E previous() next 메소드와 기능은 같고 방향만 반대 boolean hasPrevious() hasNext 메소드와 기능은 같고 방향만 반대 void add(E e) 인스턴스의 추가 void set(E e) 인스턴스의 변경 |
'자바 > 자바 입문 공부일지' 카테고리의 다른 글
자바 기초 공부 일지 40. 컬렉션 프레임 워크 (3) TreeSet<E> (0) | 2022.11.02 |
---|---|
자바 기초 공부 일지 39. 컬렉션 프레임 워크 (2) Set<E> (0) | 2022.11.02 |
자바 기초 공부 일지 37. 제네릭generic 메소드 (0) | 2022.11.02 |
자바 기초 공부 일지 36. 제네릭generic 타입 인자 (0) | 2022.11.02 |
자바 기초 공부 일지 35. 제네릭generic 의 기본 문법 (0) | 2022.11.02 |