╱╱╭╮╱╱╱╱╱╱╭━━━╮╱╱╱╭╮╱╭╮╱╱╱╱╱╱ ╱╱┃┃╱╱╱╱╱╱┃╭━╮┃╱╱╱┃┃╱┃┃╱╱╱╱╱╱ ╱╱┃┣━━┳━━╮┃┃╱┃┣━╮╱┃╰━╯┣━━┳━╮╱ ╭╮┃┃╭╮┃┃━┫┃╰━╯┃╭╮╮┃╭━╮┃╭╮┃╭╮╮ ┃╰╯┃╭╮┃┃━┫┃╭━╮┃┃┃┃┃┃╱┃┃╭╮┃┃┃┃ ╰━━┻╯╰┻━━╯╰╯╱╰┻╯╰╯╰╯╱╰┻╯╰┻╯╰╯

Java/Java 기초

[Java] 컬렉션 프레임워크 List (ArrayList, LinkedList)

재안안 2022. 4. 27. 15:23

컬렉션 프레임워크(collection framework)란 다수의 데이터들을 쉽게 다루기위해 만들어진 클래스들의 집합체이다.

 

컬렉션 프레임워크에서 제공하는 클래스들은 수많은 사람들을 통해 표준화되었고 이로인해 각 상황에 맞춰서 편하게 사용만 하면 된다.

 

컬렉션 프레임워크에서 제공되는 클래스들은 인터페이스의 형태로 만들어져 있다.

사용시 클래스로 구현해야 한다.

 

자바 컬렉션 프레임워크는 크게 세단위로 나눌 수 있다.

 

  • List<E>
  • Set<E>
  • Map<K,V>

 

컬렉션 프레임에 대해 바로 알아보기전에 먼저 알아야하는 개념이 있다.

 

바로 컬렉션 프레임워크의 관계이다.

 

컬렉션 프레임워크 인터페이스 상속관계

 

위의 사진에서 볼 수 있듯 list와 set은 공통된 부모 인터페이스를 상속한다.

 

위의 사실을 통해 기억해야하는건

 

listset에서 사용하는 메소드들중 공통된 메소드들은 collection에 저장되어 있다는 것이다.

또한 사용하는 대부분의 메소드들이 collection에 저장되어 있다.

 

  • List<E>

 

이번엔 List<E>에 대해 알아볼 것이다.

 

우선 첫번째로 List<E>는 인터페이스이고 제네릭을 사용한다.

 

인터페이스의 강제성으로 인해 List를 구현하는 모든 클래스는 데이터를 일렬로 나열하는 구조와 다양한 메소드를 갖는다.

 

추가적으로 List<E>를 구현한 클래스는 데이터의 저장(구조)에 있어서

 

요소들에 대한 "순서를 구분"하고 "중복을 허용"한다.

 

List<E>를 구현한 클래스들은 아래와 같은 메소드들을 포함한다.

 

메소드 기능
add(int index, E elem) index 위치에 요소 추가
get(int index) index 위치 값 얻기
indexOf(Object o) 요소 인덱스 값 얻기
listiterator() listiterator()반환
remove(int index) index 위치의 요소 삭제후 값 반환
set(int index, E elem) index 위치의 요소 변경

 

그럼 이제 list<E>를 구현한 클래스와 특징들에 대해서 알아보겠다.

 

  • ArrayList<E> : 클래스 내부의 배열을 이용해 데이터를 저장한다. (요소 주소값 연속o)
  • LinkedList<E> : 하나의 데이터가 다음 데이터의 주소값을 포함하는 형식으로 저장한다. (요소 주소값 연속x)

 

우선 ArrayList부터 사용해보겠다.

 

ArrayList 사용 예제

  • 우선 ArrayList를 import 하였다.
  • ArrayList 생성시 ArrayList의 제네릭에 클래스 자료형을 지정해주었다.
  • ArrayList에 정의되어있는 메소드들을 사용하였다.

 

ArrayList는 분명 클래스이다. ArrayList에서 데이터를 저장하는 방법은 아래와 같다.

 

클래스 내부에 존재하는 배열을 통해 데이터를 추가로 저장하기도하고 제거하기도한다.

배열을 통해 데이터를 추가, 제거를 하니 결국 요소가 변경될 때마다

 

새로운 배열이 생성된다는 것이다.

 

요소를 추가할 때마다 배열의 크기가 요소의 크기만큼 커진다.

 

결국 클래스의 메모리는 순차적으로 늘어난다.

 

이제 실행 결과를 보겠다.

 

실행 결과

 

 

이제 LinkedList를 만들어 보겠다.

 

LinkedList 사용 예제

  • 우선 LinkedList를 import 하였다.
  • ArrayList 생성시 LinkedList의 제네릭에 클래스 자료형을 지정해주었다.
  • ArrayList에 정의되어있는 메소드들을 사용하였다.

 

LinkedList는 하나의 객체를 저장할 때 원하는 값만 저장하는 것이 아니라 원하는 값 + 다음에 저장할 데이터의 주소를 저장한다.

결국 저장된 데이터를 불러오면 다음 요소의 주소를 함께 불러오는 것이다.

요소들끼리 꼬리를 물기 때문에 배열을 통하지 않아도 인덱스를 통해 나열한 것처럼 저장할 수 있는 것이다. 

 

이해를 돕기위해 아래에서 메모리상 데이터를 시각화 하였다.

 

LinkedList vs. ArrayList<E>

 

실행 결과를 보겠다.

 

 

정리하자면 ArrayListLinkedList사용방법은 똑같다고 볼 수 있다.

결국 각 메소드들은 동일하게 존재하고 출력값과 원하는 값이 일치하기 때문이다.

 

그런데 ArrayList와 LinkedList의 차이점이 있다.

 

일단 데이터를 순회하는 속도, 데이터를 처리하는 LinkedList가 압도적으로 빠르다.

 

만약 ArrayList에서 요소 하나를 삭제한다면,

새로운 배열이 만들어지고 데이터들은 한자리 앞으로 당겨진다. (많은 작업)

 

그러나 만약 LinkedList에서 요소 하나를 삭제한다면,

삭제할 요소의 주소를 가지고있는 이전 요소에게 다음 요소의 주소값을 넣어주기만 하면 되기 때문이다. (적은 작업)

 

그러나 LinkedList는 데이터 순회도중 현재 요소에서 이전요소로 접근하기가 매우 어렵다.

ArrayList는 속도면에서는 상대적으로 느리지만

요소 탐색에 좀 더 용이하다.

 

차이점이 있으니 상황에 따라 적절히 사용해야한다.

 

그런데 보통 알고리즘 문제가 아닌이상 ArrayList를 가장 많이 쓴다.