3월 19, 2024

[Java] set과 list의 차이점

1. set과 list의 차이점

기술면접을 볼 때 자주 물어보는 질문 중 하나가 set과 list의 차이점이다. 

쉬운 내용 같지만 막상 질문을 받으면 생각나지 않을 수 있으니 잘 정리해두자.


간단하게 한꺼번에 정리를 해보겠다.

1. Set은 중복을 허용하지 않는 반면, list는 중복을 허용한다.

2. Set은 순서가 없는 (보장되지 않는) 반면, list는 순서가 존재한다. 

=> 따라서 list는 index라는 개념이 존재하고, set은 index라는 개념이 존재하지 않는다. 

 

아래 추가적인 set과 list에 대한 개념, 그리고 각각을 java에서 구현할 때 조심해야 할 점에 대해 작성해놓았다.



2. set 부연설명

자세히 설명을 해보자면, set은 말 그대로 '집합'의 개념이다. 우리가 수학시간에 배웠던 집합을 생각하더라도 집합에는 중복된 원소가 들어갈 수 없다. 따라서 set collection은 중복된 원소를 하나로 계산하고 싶을 때 쓰면 유용하다. 예를 들어, for 문을 돌면서 모든 원소를 추가해주어야 하는데, 이전에 똑같은 원소가 들어간 것이 있을 경우에는 두 번 count하지 않고 싶을 때 쓰면 매우 유용하다. 

 

여기서 주의할 점이 있다. set의 경우 중복을 허용하지 않는다고 했는데, 그러면 Java 내에서 중복은 어떤 방식으로 검사를 하는가를 생각해보자. Java에서는 단순 primitive type 이외에도 다양한 객체가 존재하기 때문에 필요에 따라서 특정 객체를 set에 넣기 위해서는 같음을 어떻게 정의할 것인지에 대한 코드가 필요하다. 

 

예를 들어 hashSet같은 경우에는 hashCode(), equals()를 가지고 비교를 하게 된다. 따라서 이 경우에 set이 우리가 원하는 방식대로 중복을 처리해주기 위해서는 추가적인 구현이 필요하게 된다. 

 

set 자료구조는 빠르다는 장점을 가지고 있지만 모든 element를 순회할 때 list에 비해 직관적이지는 않다. Iterator를 사용하여 hasNext()로 순회를 하거나, 아니면 for each loop을 사용하는 방법도 가능하다.


3. list 부연설명

반면 list의 경우에는 우리 일상생활에서 쉽게 접할 수 있듯이 순서를 가지고 있는 자료구조이다. 따라서 원소마다 순서가 붙게 되고 그것을 index라고 주로 정의한다. 따라서 index가 정의되어 있기 때문에 똑같은 객체가 두 번 들어와도 전혀 지장이 없으며, 같은 객체더라도 set과는 달리 다른 index에 서로 같은 객체가 들어 올 수 있다. 

 

Java에서는 list 아래 ArrayList와 LinkedList가 정의되어 있고, 둘 다 자주 사용되는 자료구조이다. ArrayList는 LinkedList에 비해 빠르고 크기를 자유롭게 조절할 수 있는 배열을 뜻한다. 따라서 초기에 java의 primitive type으로 배열과 배열의 크기를 선언하지 않더라도 마음대로 객체를 추가하고 제거할 수 있다는 장점이 있다. LinkedList는 arraylist와 달리, iterator를 사용하여 모든 원소를 순회한다. 


중복을 허용하지 않아야 할 때 (똑같은 것을 두 번 세지 않아야 할 때 )는 set을, index를 기반으로 하여 쉽게 순회하고 싶고 순서가 필요한 경우에는 list를 쓴다고 간단히 알아두면 될 것 같다.