본문 바로가기
Java/Java

[Java] 컬렉션 프레임워크 - List<E> 인터페이스

by 기록하는_사람 2022. 10. 18.

컬렉션 프레임워크

📌 컬렉션 프레임워크

: 데이터 저장 방법과 알고리즘에 대한 프레임워크.

 

List<E> 인터페이스

📌 List<E> 인터페이스를 구현하는 컬렉션 클래스

① ArrayList<E> 

: 배열 기반 자료구조, 배열을 이용해 인스턴스 저장,

② LinkedList<E> 

: 리스트 기반 자료구조, 리스트를 구성해 인스턴스 저장. 

 

📌 List<E> 인터페이스를 구현하는 컬렉션 클래스의 특징

① 인스턴스의 저장 순서를 유지함. 

② 동일한 인스턴스의 중복 저장을 허용함.

 

📌 ArrayList<E> vs  LinkedList<E>

  장점 단점
ArrayList<E> - 저장된 인스턴스의 참조가 빠름. - 저장 공간을 늘리는 과정에서 시간이 많이 소요됨.
- 인스턴스 삭제 과정에서 많은 연산 필요. 느림. 
LinkedList<E> - 저장 공간을 늘리는 과정이 간단함. 
- 저장된 인스턴스 삭제 과정 단순함. 
- 저장된 인스턴스의 참조 과정이 복잡함. 느림. 

 

ArrayList<E> 클래스

📌 ArrayList<E> 클래스

List<String> list = new ArrayList<>();

 

📌 인스턴스 저장

list.add("a");

 

📌 인스턴스 순차적 참조 방식

for(int i = 0; i < list.size(); i++) {
	System.out.print(list.get(i) + ' ');
}

 

📌 인스턴스 삭제

list.remove(0);  // 0번 인덱스에 위치한 인스턴스 삭제.

 

📌 ArrayList<E> 인스턴스는 내부적으로 배열을 생성해 인스턴스를 저장하고, 필요 시 스스로 배열의 길이를 늘림.

 

📌 장점

① 저장된 인스턴스 참조가 빠름. 

 

📌 단점

① 저장 공간을 늘리는 과정에서 시간이 많이 소요됨.

② 인스턴스 삭제 과정에서 많은 연산이 필요할 수 있고, 속도가 느림.

 

LinkedList<E> 클래스

📌 LinkedList<E> 클래스

: 노드로 연결되어 있음. 

List<String> list = new LinkedList<>();

 

📌 인스턴스 저장

: 노드 추가하고 앞 뒤 노드와 연결하고, 인스턴스 저장함. 

 

📌 인스턴스 순차적 참조 방식

 

📌 인스턴스 삭제

: 해당 인스턴스가 저장된 노드 삭제.

 

📌 노드를 추가, 삭제하므로, 인스턴스 저장 공간을 미리 생성할 필요가 없음. 

 

📌 장점

① 저장 공간을 늘리는 과정이 간단. 

② 저장된 인스턴스의 삭제 과정이 단순. 

 

📌 단점

① 저장된 인스턴스의 참조 과정이 복잡하여, 속도가 느림. 

 

인스턴스에 순차적 접근 방법

📌 인스턴스에 순차적 접근 방법

① enhanced for문 사용.

반복자  사용.

 

📌 enhanced for문 사용

📄 EnhancedForTest.java

package list;

import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;

public class EnhancedForTest {

	public static void main(String[] args) {
		System.out.println("---ArrayList---");
		List<String> list = new ArrayList<>();
		
		// 인스턴스 저장.
		list.add("red");
		list.add("blue");
		list.add("purple");
		
		// 인스턴스 참조.
		for(String s : list) {
			System.out.print(s + " ");  // red blue purple 
		}
		System.out.println();
		
		// 인스턴스 삭제.
		list.remove(1);

		// 인스턴스 참조.
		for(String s : list) {
			System.out.print(s + " ");  // red purple 
		}
		System.out.println();
		
		System.out.println("---LinkedList---");
		List<String> list2 = new LinkedList<>();
		
		// 인스턴스 저장.
		list2.add("apple");
		list2.add("banana");
		list2.add("cherry");
		
		// 인스턴스 참조.
		for(String s : list2) {
			System.out.print(s + ' ');  // apple banana cherry
		}
		System.out.println();
		
		// 인스턴스 삭제.
		list2.remove(2);

		// 인스턴스 참조.
		for(String s : list2) {
			System.out.print(s + ' ');  // apple banana 
		}
		System.out.println();

	}

}

 

📌 반복자 사용.

Iterator<T> iterator()

E next()  // 다음 인스턴스 참조 값 반환.
boolean hasNext()  // next 메소드 호출 시 참조 값 반환 가능 여부 확인.
void remove()  // next 메소드 호출을 통해 반환했던 인스턴스 삭제.

📄 IteratorTest.java

package list;

import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
import java.util.Iterator;


public class IteratorTest {

	public static void main(String[] args) {
		/* ArrayList */ 
		System.out.println("---ArrayList---");
		List<String> list = new ArrayList<>();
		
		// 인스턴스 저장.
		list.add("red");
		list.add("blue");
		list.add("purple");
		
		Iterator<String> it = list.iterator();  // 반복자. 
		
		// 인스턴스 참조.
		while(it.hasNext()) {
			System.out.print(it.next() + " ");  // red blue purple
		}
		System.out.println();
		
		// 인스턴스 삭제. 
		it = list.iterator();  // 반복자 다시 받음. 
		
		String str;
		while(it.hasNext()) {
			str = it.next();
			if(str.equals("blue")) {  // blue 삭제. 
				it.remove();
			}
		}
		
		// 인스턴스 참조.
		it = list.iterator();  // 반복자 다시 받음. 
		
		while(it.hasNext()) {
			System.out.print(it.next() + " ");  // red purple 
		}
		System.out.println();
		
		/* LinkedList */ 
		System.out.println("---LinkedList---");
		List<String> list2 = new LinkedList<>();
		
		// 인스턴스 저장.
		list2.add("apple");
		list2.add("banana");
		list2.add("cherry");
		
		Iterator<String> it2 = list2.iterator();  // 반복자. 
		
		// 인스턴스 참조.
		while(it2.hasNext()) {
			System.out.print(it2.next() + " ");  // apple banana cherry 
		}
		System.out.println();
		
		// 인스턴스 삭제. 
		it2 = list2.iterator();  // 반복자 다시 받음. 
		
		String str2;
		while(it2.hasNext()) {
			str2 = it2.next();
			if(str2.equals("apple")) {  // apple 삭제.
				it2.remove();
			}
		}
		
		// 인스턴스 참조.
		it2 = list2.iterator();  // 반복자 다시 받음. 
		
		while(it2.hasNext()) {
			System.out.print(it2.next() + " ");  // banana cherry 
		}
		System.out.println();
	}

}

 

양방향 반복자

📌 양방향 반복자

: List<E>를 구현하는 클래스의 인스턴스들만 사용 가능한 반복자. 

public ListIterator<E> listIterator()

E next()  // 다음 인스턴스 참조 값 반환.
boolean hasNext()  // next 메소드 호출 시 참조 값 반환 가능 여부 확인.
void remove()  // next 메소드 호출을 통해 반환했던 인스턴스 삭제.

E previous()  // 이전 인스턴스 참조 값 반환.
boolean hasPrevious()  // previous 메소드 호출 시 참조 값 반환 가능 여부 확인.

void add(E e)  // 인스턴스 추가.
void set(E e)  // 인스턴스 변경.

 

📄 ListIteratorTest.java

package list;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Iterator;
import java.util.List;
import java.util.ListIterator;

public class ListIteratorTest {

	public static void main(String[] args) {
		List<String> list = Arrays.asList("apple", "banana", "cherry", "pear", "orange");
		list = new ArrayList<>(list);
		
		ListIterator<String> it = list.listIterator();  // 양방향 반복자. 
		
		String str;
		while(it.hasNext()) {  // 왼쪽에서 오른쪽으로 이동. 
			str = it.next();
			System.out.print(str + ' ');  // apple banana cherry pear orange
			if(str.equals("banana")) {  // "banana"를 만날 경우, 
				it.add("bananana");  // "bananana" 추가. 
			}
		}
		System.out.println();
		
		while(it.hasPrevious()) {  // 오른쪽에서 왼쪽으로 이동.
			str = it.previous();
			System.out.print(str + " ");  // orange pear cherry bananana banana apple
			if(str.equals("cherry")) {  // "cherry"를 만날 경우,
				it.set("blueberry");  // "blueberru" 추가. 
			}
		}
		System.out.println();
		
		for(Iterator<String> it2 = list.iterator(); it2.hasNext();) { // 왼쪽에서 오른쪽으로 이동. 
			System.out.print(it2.next() + ' ');  // apple banana bananana blueberry pear orange 
		}
		System.out.println();
	}

}

댓글