List, Map 과 Set에 대해 조금만 알아보자.

2019. 5. 9. 16:27자료구조

왜죠?

왜 알아야 되는지 전혀 와닿지 않았다. 뭐 중요하단 이야기는 굉장히 많이 들었지. 대략 어느 때에 List를 사용해야 할지, 어느 때에 Map을 사용해야 할지 하지만 Set을 사용할 때는 몰랐다. 뭐 자료구조를 많이 사용하는 것만 알고 있다면 어느정도 코딩을 하는데 전~혀 문제가 없다고 생각을 했었다. 딱! 알고리즘을 풀기 전까지. 그리고 면접 보는 자리에서 코딩테스트를 하면서 엄청나게 혼나기( 혼난건 아니지만 왠지 주눅들었었다.)전 까지 말이다.

 

예로 코딩테스트를 보는 곳에서 Restful하게 문장을 CRUD하게 만드는 것이었다. 1시간안에.(알고리즘 2문제도 포함해서)

테스트에는 DB를 사용하지 않고 만들라는 요구가 있었는데, 차라리 DB있이 만들었다면... JPA를 사용했다면 이런 사단이 나지 않았을 것이다. 

 

한번도 생각해 보지 않았다. Repository(레파지토리)를 내가 만들어야 한다면 List를 사용할 것인가, 아니면 Map을 아니라면 Set을 사용해서 만들 것인가? 우선 나는 List를 그것도 Arraylist를 사용했었다. 사실 만들면서도 커다란 문제가 있다고 생각을 했었지만, 당시 1시간안에 RestAPI와 알고리즘 두문제를 풀어야 하는 시점에서 레파지토리에 대해서는 생각을 할 겨를이 없었다.(변명이다. 만약 내가 진작에 생각을 했었다면...) 

 

시작하기 전

내용을 한 페이지에 적기에는 내용들이 너무 방대하고 많기 때문에 요약 정리만 할 예정이다. 

당연히 자료구조 하나하나 중요한 내용이기 때문에 따로 하나하나 정리하겠지만.

 

JCF(Java Collection Framework)

JCF는 자바(JAVA)에서 데이터를 저장하는 기본적인 자료구조들을 모아 관리하고 제공하는 아주 간편한 프레임워크다.

아래 사진을보며 JCF의 구조를 한번 바라보자.

JCF Image

JCF에는 커다랗게 Collection과 Map이 있다.( Map도 Collection 안에 속해 있는줄 알았지만 아니였더라.)

List와 Set은 Collection을 상속 받고 있다. Map은 Collection과 동등한 위치에 있다는 것을 알 수 있다. 하지만 그림과 다르게 얼마 전 우선순위 큐(Priority Queue)를 사용하면서 Queue도 Collection에 속해 있다는 것을 알게 되고 사진을 한번 찾아 보았다. 

Queue 또한 Collection에 속해 있다는 것을 잊지말자.

그림마다 차이가 조금씩 있지만 두그림을 보면 어느 Stack과 Queue가 어디에 속해있는지 확인 할 수 있으니 한번 훑어 보는 것도 좋을 것 같다.

 

생각해보면 Collection에 속해 있는 List와 Set 그리고 Queue에는 add() 메소드가 가능 했었지만, map은 put()메소드를 사용하지 않았나? 인터페이스가 달랐기 때문이였다.

List Interface

내 생각이지만 가장 많이 사용하는 자료구조 일 것이다. 처음 자바를 공부했을 때, 옆에 친구는 배열보다도 list를 먼저 알았으니 말이다. 배열 알필요 있어? Arraylist만 알면 되는거 아닌가? 편하고 좋지 뭐. 그렇다. 굉장히 좋다. 배열 처럼 배열 크기 정해줄 필요 없으며, remove() 메소드를 사용하면 필요 없는 것들은 알아서 삭제 까지 해주니 굉장히 편한 자료구조다. 나도 항상 사용했던 자료구조이니 만큼 특징에 대해서 이야기 해보자.

 

List는 요소들의 순서를 저장하여 Index를 사용하여 특정 위치에 요소를 삽입하거나 접근할 수 있으며 중복 요소를 허용한다. 

 

ArrayList

ArrayList는 상당히 빠르고 크기를 마음대로 조절할 수 있는 배열이다. 

단방향 포인터 구조로 자료에 대한 순차적인 접근에 강점이 있다. (나중에 정리 하겠지만 삭제 또는 삽입이 빈번할 경우에 왜 LinkedList보다 안 좋은지에 대해 설명하겠다.) 

 

Vector

ArrayList의 구형 버전이라고 한다. 모든 메소드가 동기화 되어있다.

하지만 한번도 사용해본 적도 사용하는 것을 본적도 없는...

 

LinkedList

양방향 포인터 구조로 데이터의 삽입, 삭제가 빈번할 경우 빠른 성능을 보장한다.

스택과 큐, 양방향 큐등을 만들기 위해 많이 사용한다.

 

Set Interface

Set은 순서를 신경쓰지 않는다. 데이터가 존재하냐 안하냐의 문제에 중점을 둔다.

그리고 Set은 같은 요소의 중복 저장을 허용하지 않는다.(물론 전부 중복 저장을 허용하지 않는 것은 아니다. TreeSet 같은 경우는 중복 저장을 허용한다.)

List 인터페이스와 다르게 상위 메소드만 사용한다. 

 

사실 현재 개발을 별로 해보지 않은 상태에서 Set 인터페이스를 많이 사용해 보지 않은 것은 사실이지만, 중요한 자료구조인 것은 확실하니... 다시 공부하도록ㅎㅎㅎ

 

HashSet

HashSet은 별도의 정렬 작업이 없어 Set인터페이스에서 가장 빠른 임의 접근 속도를 자랑한다.

하지만 단점은 순서를 전혀 예측할 수 없다는 것이다.

 

LinkedHashSet

LinkedHashSet은 추가된 순서, 또는 가장 최근에 접근한 순서대로 접근이 가능하다.

TreeSet

TreeSet은 정렬된 순서대로 보관하며 정렬 방법을 지정할 수 있다.

 

Map Interface

Map은 Collection과 다르게 Key(키)와 Value(값)의 쌍으로 연관지어 저장하는 객체이다. Map은 Set과 다르게 중복이 허용된다.(많은 곳에서 질문이 들어와서...)

위에서 언급했던 레파지토리 구조가 어떻게 되어있는지 직접 보지는 못했지만, 나의 생각은 Map 그중 HashMap으로 만들었다면 CRUD를 했을 때 가장 효과 적이였을 것이라 생각한다. 

 

HashMap

HashMap은 중복을 허용하지 않고 순서를 보장하지 않는다. 

Key와 Value 값으로 null이 허용된다.

 

HashTable

HashMap보다는 느리지만 동기화가 지원된다.

HashMap과 다르게 Key와 Value값으로 null이 허용되지 않는다.

 

TreeMap

이진 검색트리의 형태로 키와 값으로 되어있는 데이터를 저장한다.

정렬된 순서로 키와 값을 저장하므로 빠른 검색이 가능하다.

저장시 정렬(오름차순)을 하기 때문에 저장시간이 다소 오래 걸린다.

 

LinkedHashMap

기본적으로 HashMap을 상속받아 HashMap과 매우 비슷하다.

Map에 있는 엔트리들의 연결 리스트를 유지하므로 입력한 순서 반대로 반복 가능하다.

'자료구조' 카테고리의 다른 글

큐(queue) 자바로 만들어보기  (0) 2019.03.14