brunch

You can make anything
by writing

C.S.Lewis

컬렉션프레임워크 - List

* 이 내용은 철저히 초심자를 위해 알기 쉽게 설명하는 것을 목적으로 하고 있습니다.

* 더 정확하고 자세한 개념은 다른 고수님들의 글들을 참고하시길 바랍니다.

* 그리고 이 글에서는 코드 최소한으로 다루고 있습니다.


자료구조라는 단어를 들어 보신 적이 있나요?

자료구조는 말 그대로 자료(data)의 구조(structure)가 어떻게 생겼는지를 살펴보는 내용입니다.

우리가 앞에서 배운 대표적인 자료구조는 변수와 배열이 있습니다. 클래스도 있다고요? 클래스도 데이터를 담긴 하지만 모양이 변화무쌍하여 클래스자체의 자료구조는 없다고 보는 게 맞습니다.

어쨌든, 우리가 알고 있는 변수와 배열에는 각각의 한계가 있었습니다. 변수는 하나의 데이터 밖에 담지 못한다는 점과 배열은 크기를 지정해야만 한다는 점이었죠.


그래서 자바에서는 보다 더 유용한 자구조를 만들어 제공하는데, 바로 Collection Framework입니다.

이 자료구조는 컬렉션 인터페이스를 상속받는 리스트와 셋 인터페이스, 그리고 독립적으로 맵 인터페이스가 있습니다. 그리고 각각의 인터페이스를 구현하는 클래스들이 있습니다.

여러 클래스가 있지만 자주 사용하는 친구들만 다뤄보도록 하겠습니다.

우리가 다형성과 추상화를 배운 이상 위 그림에서 예상되는 점이 있을 겁니다.


1. 각 인터페이스를 구현받는 클래스들은 사용법이 거의 똑같겠구나!

2. 이 클래스들은 상위 인터페이스의 형태로 들어갈 수 있겠구나!


List Collection

List는 배열과 같은 형태를 가지고 있습니다.

같은 데이터 타입의 값을 여러 개 넣을 수 있고, 시작점을 기준으로 몇 번째 떨어진 곳에 데이터가 있는지 알 수 있는 인덱스 번호가 있습니다.

하지만 결정적으로 만들 때 크기를  지정하고, 그 이상을 넘지 못하는 배열과 달리 List는 정해진 크기를 넘어도 문제가 발생하지 않습니다.

오히려 크기를 지정하지 않고 사용하는 경우가 더 많습니다. 왜냐면 List는 사실상 크기가 무제한 이기 때문입니다.


그런 리스트 중에 가장 많이 사용되는 ArrayList 클래스를 알아보겠습니다.

ArrayList는 List 인터페이스를 구현받았으므로 기능은 동일합니다. 다만 추가 삭제 시 독특한 점이 있습니다. 추가 시 추가 위치 이후의 데이터들이 모두 한 자리씩 뒤로 물러나야 하고, 삭제 시에는 빈자리로 모두 이동해야 한다는 점입니다.


이게 얼마나 불편한 일인지 생활 속으로 들어가 봅시다.

우리가 흔히 영화관에서 영화를 볼 때 가끔 화장실을 다녀오기 위해 다른 사람을 지나쳐야 하죠? 많이 민망한 상황입니다. 하지만 리스트에선 더한 일이 일어나곤 하는데요.

1번 자리에 있는 사람이 자리를 비우면 나머지 사람들이 빈자리를 메우기 위해서 모두 한 칸씩 이동해야 하는 상황이 생기는 것이죠! 그런데 자리를 비운 사람이 눈치 없이 1번 자리에 다시 앉겠다고 한다 면요? 나머지 사람들은 다시 반대로 한 칸씩 이동해야 합니다.

이런 상황이 자주 일어난다면 상당히 많은 사람들이 불편할 것입니다.


그럼 이건 어떨까요?

방금 과 마찬가지로 1번 자리에 있던 사람이 자리를 떠나면 나머지 사람들이 빈칸으로 이동하는 것이 아니라, 내 옆에 누구였는데 누구로 바뀌었구나 하고 기억하는 것입니다.

이러면 누군가가 자리를 비우거나 다시 돌아와도 자리에 변화가 생긴 양쪽 사람들만 기억을 다시 해 주면 되므로 많은 사람들이 불편해질 필요가 없습니다. 이것이 LinkedList라는 녀석입니다.


그래서 LinkedList는 각 위치의 좌우에 옆자리에 누가 있는지를 기억하는 저장공간이 위치합니다.

하지만 추가될 때 내 옆에 누구 인지를 모두 기억해야 하므로 조금 번거로울 수도 있겠죠?

그래서 ArrayList는 중간 위치에 추가 삭제가 거의 없는 경우 유용한 반면, LinkedList는 중간에 추가삭제가 빈번할 경우 유용합니다.


그리고 Vector는 구조적으로는 ArrayList와 완전히 동일하지만 StringBuffer와 StringBuilder의 차이처럼 동기화 지원 여부가 다릅니다.

즉, Vector는 누군가가 사용 중이라면 다른 누군가는 사용하지 못하고 기다려야 합니다.  이 부분은 스레드(thread)에서 자세히 다룰 것입니다.


앞서 밝혔듯이 List 인터페이스를 구현받는 이들은 다형성에 의해 List 형태로 담을 수 있습니다.

또한 추상화를 활용하여 같은 규격을 사용했으므로 이들 모두 같은 메서드들을 사용니다. 그리고 그 메서드들은 굉장히 유용한 녀석들입니다. 하지만 우리는 코드가 아니라 개념과 모양을 공부하는 것이므로 이것들은 생략하도록 하겠습니다.


List를 배워봤는데 어떤 가요? 일단 크기를 꼭 지정해야만 하는 배열과 비교했을 때 상당히 편리하죠?

이런 유용한 기능을 누군가가 클래스로 제공하는 것, 그리고 그것을 누군가가 편리하게 사용하는 것, 이것이 OOP의 기본 정신이죠!

매거진의 이전글 제너릭(Generic)
브런치는 최신 브라우저에 최적화 되어있습니다. IE chrome safari