ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • Arrays.asList vs List.of 차이
    Java 2022. 11. 22. 11:51

    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을 생성해서 요소의 값을 옮겨야 합니다.

    'Java' 카테고리의 다른 글

    [JAVA] Scanner nextInt()는 '엔터'를 인식할 수 없다  (0) 2022.11.23
    [JAVA] 변수 타입 확인하기  (0) 2022.11.23
    String.format()?  (0) 2022.11.21
    ☑️[JAVA] int vs Intager / boolean vs Boolean  (0) 2022.11.17
    [JAVA] stream 기본집계  (0) 2022.11.11
Designed by Tistory.