Arrays.asList() / List.of
자바에서 Array를 List으로 변환하기 위해서는 Arrays.asList(array)
를 사용합니다.
Java 9 버전 부터는 List.of(array)
라는 새로운 팩토리 메소드를 도입했습니다.
차이점은 무엇일까요 ? 뭐가 좋은 걸까?
변경 가능 여부 (Mutable / Immutable)
Arrays.asList()로 반환된 list는 변경이 가능합니다. 하지만, List.of()에서 반환된 메서드는 변경이 불가능합니다.
List<Integer> list = Arrays.asList(1, 2, null);
list.set(1, 10); // OK
List<Integer> list = List.of(1, 2, 3);
list.set(1, 10); // Fails with UnsupportedOperationException
이유는 Arrays.asList()는 ArrayList를 반환하고, set등이 구현되었습니다. (Arrays 내부 클래스 ArrayList)
반면, List.of()는 ListN이라는 타입의 객체를 반환하는데, 이는 불변 객체(Immutable object)입니다. 따라서 수정할 수 없습니다.
(참고) Arrays.asList()가 반환하는 ArrayList 타입은 java.util.ArrayList가 가 아니라 Arrays 내부 클래스입니다. add와 remove는 구현되어 있지 않아서, 크기는 변경할 수 없습니다.
Null 허용 여부
Array.asList()는 null을 허용합니다. List.of()는 반환 객체가 생성될 때, 내부적으로 파라미터들에 대한 null체크를 하고 null을 허용하지 않습니다.
List<Integer> list = Arrays.asList(1, 2, null); // OK
List<Integer> list = List.of(1, 2, null); // Fails with NullPointerException
List.of()로 반환된 객체의 contains의 경우 파라미터로 null이 들어오면 NPE(Null pointer exception)이 발생합니다.
List<Integer> list = Arrays.asList(1, 2, 3);
list.contains(null); // Returns false
List<Integer> list = List.of(1, 2, 3);
list.contains(null); // Fails with NullPointerException
참조 / 비참조
앞서 살펴본, Arrays.asList(array)의 객체로 add와 remove를 구현할 수 없는 이유는 참조로 동작하기 때문입니다. 배열은 크기를 늘리거나 줄일 수 없죠.
Arrays.asList(array)는 참조를 사용하기 때문에 배열의 값이 변경되면 list에도 영향이 갑니다.
Integer[] array = {1,2};
List<Integer> list = Arrays.asList(array);
array[0] = 100;
System.out.println(list); // [100, 2]
List.of(array)의 결과는 값을 기반으로 독립적인 객체를 만들기 때문에 참조가 일어나지 않습니다.
Integer[] array = {1,2};
List<Integer> list = List.of(array);
array[0] = 100;
System.out.println(list); // [1, 2]
메모리 사용
Arrays.asList()는 List.of()보다 힙에 더 많은 개체를 생성하기 때문에 더 많은 오버헤드 공간을 차지합니다. 따라서, 단지 값 요소가 필요한 경우라면 List.of()가 적합합니다.
변환
예를 들어, Array를 ArrayList 또는 HashSet 등으로 변환하기 위해서는, 참조나 변경 가능 여부는 상관없고 요소만 알면 됩니다. 이 때는 List.of()가 적합합니다.
List<String> list = new ArrayList<>(List.of(array));
Set<String> set = new HashSet<>(List.of(array));
요약
위에서 언급한 내용을 종합해서 정리한 내용은 다음과 같습니다.
- Arrays.asList()는 크고 동적인 데이터에 사용하고, List.of()는 작고 변경되지 않는 데이터의 경우 사용합니다.
- List.of()는 필드 기반 구현이 있고, 내부적으로 힙 공간을 덜 사용하기에 요소 자체가 필요하다면 List.of()가 적절합니다.
- Arrays.asList()는 변경이 가능하고 thread safety 하지 않고, List.of()는 불변하고 thread safety합니다.
- Arrays.asList()는 null 요소를 허용하고 List.of()는 null 요소를 허용하지 않습니다.
- Arrays.asList(), List.of() 모두 크기는 변경할 수 없다. 크기를 바꾸려면 Collections을 생성해서 요소의 값을 옮겨야 합니다.
Reference: What is difference between List.of vs Arrays.asList
감사합니다.
'Language > Java' 카테고리의 다른 글
Java - 실수하기 쉬운 메모리 누수의 5가지 패턴! (0) | 2022.04.15 |
---|---|
Java - Concurrent Programming (Runnable, Executor, Callable, Future 등) (0) | 2022.04.03 |
Java 8 - 새로운 Date & Time 정리 (Zoda-Time) [Instant, LocalDate, Duration ...] (0) | 2022.03.16 |
Java 8 - Optional이란? (0) | 2022.03.12 |
Java 8 - Stream이란? (+ ParallelStream) (0) | 2022.03.11 |