본문 바로가기
Study/Java

[Java] Arrays.asList() vs Collections.singletonList()

by 검프 2021. 4. 9.

java.util.Colletions애는 컬렉션 프레임워크 타입의 객체에 대한 객체생성, 정렬, 병합, 검색 등의 알고리즘을 구현한 메소드가 정의되어 있어요.

저는 그중 Colltions.singletonList()를 사용해보았어요.

 

기술설명

java.util.Colletions에는 아래와 같이 메소드가 정의되어있는데요

public static <T> List<T> singletonList(T o) {
    return new SingletonList<>(o);
}

전달인자로 들어온 객체만 포함하는 불변의 리스트를 반환하는 메소드예요.

 

예제

이 기술을 사용하기 전에는

CarNames carNames = CarNames.of(Arrays.asList(new CarName("pobi")));

위와 같이 사용했는데

이후엔

CarNames carNames = CarNames.of(Collections.singletonList(new CarName("pobi")));

와 같이 사용하게 되었어요.

 

하나의 요소를 가지는 리스트를 얻기 위해 무엇을 언제사용해야할까?

List<Integer> numbers = Arrays.asList(5);
List<Integer> singletonNumbers = Collections.singletonList(5);

numbers.set(0, 8);        //가능
singletonNumbers.set(0, 8);        //UnsupportedOperationException 발생

현재는 똑똑한 인텔리제이가 인자가 한개 일 경우 Arrays.asList()말고 Collections.singletonList()을 쓰라고 알려주네요.

하지만, 무조건 Collections.singletonList()를 사용해야할까요?

억지성 예제일 수 있으나, 차이를 명확히 하는 것이 좋을 것 같아요.

Arrays.asList()를 사용하는 경우는

리스트 요소의 속성이 변경되어야 할때에요.

크기가 기본 배열 사이즈로 초기화되어있어요. 즉, 사이즈를 1로 만들기 위해 가변인자를 받음 -> 가변인자를 배열로 변경 → 1의 크기를 가지는 리스트 생성 의 과정을 거쳐요.

...
public static <T> List<T> asList(T... a) {
    return new ArrayList<>(a);
}

private static class ArrayList<E> extends AbstractList<E>
        implements RandomAccess, java.io.Serializable
{
    private final E[] a;
...
    ArrayList(E[] array) {
        a = Objects.requireNonNull(array);
    }
...
}
...

Arrays.asList()로 만들어진 리스트는 추가, 삭제가 되지 않지만 요소의 속성은 변경할 수 있어요.

Integer[] a = {1};
List<Integer> numbers = Arrays.asList(a);
numbers.set(0, 5);
System.out.println("numbers = " + numbers);    //numbers = [5]

Collections.singletonList()를 사용하는 경우

리스트 요소의 주솟값 뿐만 아니라 속성 또한 불변이어야 함을 보장해야 할 때에요.

Arrays.asList()와 달리 항상 크기가 1이에요. 1개의 인자를 받음 → 1의 크기를 가지는 리스트 생성

...
public static <T> List<T> singletonList(T o) {
        return new SingletonList<>(o);
    }

private static class SingletonList<E>
    extends AbstractList<E>
    implements RandomAccess, Serializable {
...
    private final E element;

    SingletonList(E obj)                {element = obj;}
...
}
...

Collections.singletonList()로 만들어진 리스트는 모든 변경이 불가능해요.

List<Integer> singletonNumbers = Collections.singletonList(5);
singletonNumbers.set(0, 8);        //UnsupportedOperationException 발생

 

결론

List의 요소를 set으로 변경할 수 있다는 것은 사이드 이펙트를 열어주는 것이에요. 그렇기 때문에 하나의 요소를 가지게 하며, 불변을 보장하는 Collections.singletonList() 을 쓰는 것이 더 바람직해요. (속도 측면에선 가변인자 → 배열 변환의 과정이 없기 때문에 빠르고, 메모리 측면에선 조금더 효율적으로 쓸 수 있다고 해요. )

 

Refer

https://stackoverflow.com/questions/26027396/arrays-aslist-vs-collections-singletonlist

#java #jdk #list #Collections

댓글