본문 바로가기
IT 개인 공부/Java

[Java] 컬렉션 팩토리 : of

by Libi 2021. 9. 26.
반응형

Java에서 소수의 데이터를 가지는 고정된 크기의 리스트를 선언하려면 어떻게 해야 할까?

예를 들어 1, 2, 3 정수형 데이터를 가지는 리스트를 선언할 경우 다음과 같이 리스트 객체를 선언 후 add() 메서드를 통해 정수형 데이터를 입력해줄 것이다.

List<Integer> list = new ArrayList<>();
list.add(1);
list.add(2);
list.add(3);

 

하지만 이 방법은 데이터마다 add() 메서드를 타이핑해야 하는 번거로움이 존재하며 선언된 리스트는 고정된 크기의 리스트가 아니다.

 

이는 Arrays.asList() 팩토리 메서드를 이용하면 코드를 더욱 간단하게 줄일 수 있으며 고정된 크기의 리스트가 보장된다.

List<Integer> list = Arrays.asList(1, 2, 3);

 

실제로 list.add(4)를 해보면 UnsupportedOperationException이 발생하는 것을 확인할 수 있다.

 

다만, Arrays 클래스는 List를 제외한 Set, Map 같은 다른 형태의 자료구조 팩토리 메서드를 지원하지 않는다는 단점이 있다.

 

이를 해결하기 위해선 리스트를 인수로 받거나 스트림 API 등의 방법을 통해 해결해야 한다.

Set<Integer> list = new HashSet<>(Arrays.asList(1, 2, 3));
Set<Integer> lists = Stream.of(1, 2, 3).collect(Collectors.toSet());

 

하지만 이러한 방법도 깔끔하지 않으며, 내부적으로 불필요한 객체 할당을 필요로 하는 단점이 있다.

또한, 가장 중요한 것은 자료구조 내부가 변환할 수 있다는 점이다.

 

이를 위해 자바 9부터는 컬렉션 API를 개선하여 of라는 팩토리 메서드를 제공해준다. List, Set, Map은 다음과 같이 of 팩토리 메서드를 이용해서 간단하게 생성할 수 있다.

List<Integer> list = Arrays.asList(1, 2, 3);
Set<Integer> set = Set.of(1, 2, 3);
Map<Integer, String> map = Map.of(1, "A", 2, "B", 3, "C");

 

of 팩토리 메서드를 활용하여 더욱 간단하게 자료구조를 생성할 수 있게 되었다.

 

 

마지막으로 오버로딩으로 구현된 of 메서드에 대해서 알아보자.

실제로 각 자료구조의 of 메서드를 확인해보면 0~10개의 매개변수를 가지는 of 메서드가 구현된 것을 알 수 있다.

 

또한, 11개 이상의 매개변수를 가지는 of 메서드는 가변 인수를 활용하여 제공해준다.

 

가변 인수를 활용한 of() 메서드 하나만 있으면 해결할 수 있는데 왜 굳이 0~10개의 매개변수를 가지는 of() 메서드를 오버로딩하여 구현해놓은 것일까?

 

이는 불필요한 비용을 제거하기 위해서이다.

of() 메서드는 고정된 크기를 가지는 자료구조를 생성하는 메서드라고 하였다. 일반적으로 고정된 크기의 자료구조를 선언할 때는 10개 이하의 데이터를 가질 확률이 높을 것이다.

 

가변 인수는 내부적으로 배열을 활용한다.

즉, 사용하지 않을 추가적인 배열을 할당 및 초기화한 다음 가비지 컬렉션을 통해 제거해야 하는 비용이 추가적으로 필요하기 때문에 일반적으로 활용되는 0~10개의 매개변수를 가지는 of() 메서드를 미리 구현해놓은 것이다.

List.of()뿐만 아니라 Set.of(), Map.of() 역시 마찬가지로 같은 메커니즘으로 동작한다.

 

반응형

댓글