티스토리 뷰

자바 로고

 

 

 

 

List

 

List인터페이스는 중복을 허용하면서 저장 순서가 유지되는 컬렉션을 구현하는 데 사용됩니다.

List 계층 구조

 

 

Tip) Collection은 인터페이스이고, Collections는 클래스임에 주의하자!

 

 

 

 

List 인터페이스 메소드

 

JAVA17 API - List :  https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/util/List.html

 

List (Java SE 17 & JDK 17)

Type Parameters: E - the type of elements in this list All Superinterfaces: Collection , Iterable All Known Implementing Classes: AbstractList, AbstractSequentialList, ArrayList, AttributeList, CopyOnWriteArrayList, LinkedList, RoleList, RoleUnresolvedList

docs.oracle.com

메서드 설명
void add(int index, Object element)
boolean addAll(int index, Collection c)
지정된 위치(index)에 객체(element) 또는 컬렉션에 포함된 객체들을 추가한다.
Object get(int index) 지정된 위치(Index)에 있는 객체를 반환한다.
int indexOf(Object o) 지정된 객체의 위치(index)를 반환한다.
(List의 첫 번째 요소부터 순방향으로 찾는다.)
int lastindexOf(Object o) 지정된 객체의 위치(index)를 반환한다.
(List의 마지막 요소부터 역방향으로 찾는다.)
ListIterator listIterator()
ListIterator listIterator(int index)
List의 객체에 접근할 수 있는 ListIterator를 반환한다.
Object remove(int index) 지정된 위치(index)에 있는 객체를 삭제하고 삭제된 객체를 반환한다.
Object set(int index, Object element) 지정된 위치(index)에 객체(element)를 저장한다.
void sort(Comparator c) 지정된 비교자(comparator)로 List를 정렬한다.
List subList(omt fromIndex, int toIndex) 지정된 범위(fromIndex부터 toIndex)에 있는 객체를 반환한다.

 

 

 

 

 

List의 사용법

 

ArrayList

Object배열을 이용해서 데이터를 순차적으로 저장하는 리스트이다.

JAVA17 API : ArrayList https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/util/ArrayList.html

 

ArrayList (Java SE 17 & JDK 17)

Type Parameters: E - the type of elements in this list All Implemented Interfaces: Serializable, Cloneable, Iterable , Collection , List , RandomAccess Direct Known Subclasses: AttributeList, RoleList, RoleUnresolvedList Resizable-array implementation of t

docs.oracle.com

 

ArrayList 선언방법

import java,util.List;
import java.util.ArrayList;

List<?> list1 = new ArrayList<>();
ArrayList<?> list2 = new ArrayList<>();

System.out.println(list1);
System.out.println(list2);

// 2개 다 출력 : [] 
// 즉, 둘다 아무것도 없는 상태

 

 

 

 

LinkedList

불연속적으로 존재하는 데이터를 서로 연결한 형태로 구성한 리스트이다.

Java17 API : LinkedList https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/util/LinkedList.html

 

LinkedList (Java SE 17 & JDK 17)

Type Parameters: E - the type of elements held in this collection All Implemented Interfaces: Serializable, Cloneable, Iterable , Collection , Deque , List , Queue Doubly-linked list implementation of the List and Deque interfaces. Implements all optional

docs.oracle.com

 

 

LinkedList 선언 방법

import java,util.List;
import java.util.LinkedList;

List<?> list1 = new LinkedList<>();
LinkedList<?> list2 = new LinkedList<>();

System.out.println(list1);
System.out.println(list2);

// 2개다 출력 : [] 
// 즉, 둘다 아무것도 없는 상태

 

 

 

 

LinkedList 시각적 구성 

 

링크드 리스트 기본

 내부 구성을 보면 각 요소(node)들은 자신과 연결된 다음 요소에 대한 참조(주소값)와 데이터로 구성되어 있다.

 

 

링크드 리스트 삭제

삭제하고자 하는 요소의 이전 요소가 삭제하고자 하는 요소의 다음 요소를 참조하도록 변경만 해준다.

 

 

링크스 리스트 추가

새로운 요소를 생성한 다음 추가하고자 하는 위치의 이전 요소의 참조를 새로운 요소에 대한 참조로 변경해 주고, 새로운 요소가 그다음 요소를 참조하도록 변경만 해준다.

 

 

실제 사용 중인 개선한 링크드 리스트

 

 

 

 

테스트

 

코드가 길어서 접는 글로 작성하게 되었습니다.

더보기
import java.util.*;

public class Main {
	public static void main(String[] args) {
		
		// 추가할 데이터의 개수를 고려하여 충분히 잡자!
		ArrayList al = new ArrayList(2000000);
		LinkedList li = new LinkedList();
		
		System.out.println("<= 순차적으로 추가하기 =>");
		System.out.println("ArrayList : " + sequenceAdd(al));
		System.out.println("LinkedList : " + sequenceAdd(li));
		System.out.println();
		System.out.println("<= 중간에 추가하기 =>");
		System.out.println("ArrayList : " + middleAdd(al));
		System.out.println("LinkedList : " + middleAdd(li));
		System.out.println();
		System.out.println("<= 중간에 삭제하기 =>");
		System.out.println("ArrayList : " + middleRemove(al));
		System.out.println("LinkedList : " + middleRemove(li));
		System.out.println();
		System.out.println("<= 순차적으로 삭제하기 =>");
		System.out.println("ArrayList : " + sequenceRemove(al));
		System.out.println("LinkedList : " + sequenceRemove(li));

	}
	
	public static long sequenceAdd(List list) {
		long start = System.currentTimeMillis();
		for(int i = 0; i < 1000000; i++) { list.add(i+""); }
		long end = System.currentTimeMillis();
		return end - start;
	}
	public static long middleAdd(List list) {
		long start = System.currentTimeMillis();
		for(int i = 0; i < 20000; i++) { list.add(500, "X"); }
		long end = System.currentTimeMillis();
		return end - start;
	}
	public static long sequenceRemove(List list) {
		long start = System.currentTimeMillis();
		for(int i = list.size()-1; i >= 0; i--) { list.add(i); }
		long end = System.currentTimeMillis();
		return end - start;
	}
	public static long middleRemove(List list) {
		long start = System.currentTimeMillis();
		for(int i = 0; i < 20000; i++) { list.remove(i); }
		long end = System.currentTimeMillis();
		return end - start;
	}
}

/*  숫자가 높을수록 오래걸린 것이다.
<= 순차적으로 추가하기 =>
ArrayList : 77
LinkedList : 223

<= 중간에 추가하기 =>
ArrayList : 15842
LinkedList : 22

<= 중간에 삭제하기 =>
ArrayList : 12124
LinkedList : 751

<= 순차적으로 삭제하기 =>
ArrayList : 10
LinkedList : 165
*/

 

 

 

 

 

결론

 

1. 순차적으로 추가/삭제하는 경우에는 ArrayList가 LinkedList보다 빠르다.

2. 중간 데이터를 추가/삭제하는 경우에는 LinkedList가 ArrayList보다 빠르다.

 

 

컬렉션 읽기 접근시간 구현 비고
ArrayList 빠르다. 느리다. Stack을 구현한다면  순차적인 추가삭제는 더 빠르다.
하지만 비효율적인 메모리를 사용한다.
즉, 데이터 개수가 변하지 않는 경우 최상의 선택!
LinkedList 느리다. 빠르다. Queue을 구현한다면 데이터가 많을 수록 접근성이 떨어진다.
즉, 데이터 개수의 변경이 잦은 경우 최상의 선택!

 

 

 

 

감사합니다.

 

 

 

 

 

공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2024/12   »
1 2 3 4 5 6 7
8 9 10 11 12 13 14
15 16 17 18 19 20 21
22 23 24 25 26 27 28
29 30 31
글 보관함