Collections.emptyList () 대 새 인스턴스


241

실제로, 더 나은처럼 빈 목록을 반환하는 :

return Collections.emptyList();

또는 이렇게 :

return new ArrayList<Foo>();

아니면 이것이 반환 된 목록으로 무엇을 할 것인지에 전적으로 의존합니까?

답변:


300

가장 큰 차이점은 변경 불가능한 목록, 즉 요소를 추가 할 수없는 목록을 Collections.emptyList()반환한다는 것 입니다. ( Java 9에 도입 된 것과 동일합니다. )List.of()

당신이 드문 경우 않는 반환 된 목록을 수정하려면, Collections.emptyList()List.of()따라서 있습니다 하지 좋은 선택이.

계약 (문서)이 명시 적으로 다르게 명시되지 않는 한 불변 목록을 반환하는 것은 완벽하게 좋습니다 (그리고 선호하는 방법).


또한 emptyList() 매번 호출 할 때마다 새 개체를 만들지 못할 수 있습니다.

이 메소드의 구현은 각 호출에 대해 별도의 List 객체를 만들 필요는 없습니다. 이 방법을 사용하면 비슷한 이름의 필드를 사용하는 것과 비슷한 비용이들 수 있습니다. (이 방법과 달리이 필드는 유형 안전을 제공하지 않습니다.)

구현은 emptyList다음과 같습니다.

public static final <T> List<T> emptyList() {
    return (List<T>) EMPTY_LIST;
}

따라서 빈 목록을 반환하는 메서드를 자주 호출하는 경우이 방법을 사용하면 CPU와 메모리 측면에서 성능이 약간 향상 될 수 있습니다.


4
그렇다면 Collections.emptyList()오류 확인 등에 더 적합할까요?
mre

1
API 클라이언트는 대신 NullPointerException에 리턴하여 얻을 수 없습니다 . Collections.emptyList()null
realPK

@PK_J는 중요한 포인트입니다. Collections.emptyList()반복 가능하고 길이를 리턴하므로 예외가 발생하지 않고 for 루프에서 사용될 수 있습니다.
ndm13

사용하는 것은 List.of()어떻습니까?

4
@AJW, 예. 그러나 new ArrayList<>()디자인 결정 과 비교하면 분명하다. 요소는이 목록에 추가되지 않습니다.
aioobe

51

Java 5.0부터 컨테이너에 요소 유형을 지정할 수 있습니다.

Collections.<Foo>emptyList()

비어있는 빈 목록을 반환하려는 경우이 방법을 사용해야한다는 다른 응답과 동의합니다.


38
Java 7부터는 컴파일러가 대상 유형에서 일반 메소드 호출의 유형 매개 변수를 유추 할 수 있습니다.List<Foo> list = Collections.emptyList()
Paul Jackson

28

Collections.emptyList 두 버전 사이에 차이가 있으므로 반환 된 값의 사용자를 고려해야합니다.

반환하면 new ArrayList<Foo>항상 개체의 새 인스턴스가 만들어 지므로 개체와 관련된 약간의 추가 비용이 발생하여 사용할 이유가 생길 수 있습니다 Collections.emptyList. 내가 사용하는 같은 emptyList더 읽기 때문에 단지.


14

그래도 조심하십시오. 당신이 돌아 오면 Collections.emptyList()한 후이 좋아하는 몇 가지 변경을하려고 add()하거나 그런 떨어지게, U는 것 UnsupportedOperationException()때문에 Collections.emptyList()돌아 불변의 객체를.


7

나는 함께 갈 것 Collections.emptyList()그렇지 않으면 내가 옵션 2로 갈 것, 반환 된리스트 (목록은 불변으로) 어떤 식 으로든 수정되지 않을 경우.

이점은 Collections.emptyList()매번 동일한 정적 인스턴스가 리턴되므로 각 호출에 대해 인스턴스 작성이 발생하지 않는다는 것입니다.


3

리턴 된 목록이 수정되지 않도록하려면 Collections.emptyList ()를 사용하십시오. 이것은 emptyList ()를 호출 할 때 반환되는 것입니다.

/**
 * The empty list (immutable). 
 */
public static final List EMPTY_LIST = new EmptyList();

전화 Collections.emptyList()에 건설 비용이 있는지 알아 보려고 여기에 도착했습니다 . 구현 세부 정보를 보면 (모든 JVM에서 동일하지는 않지만) 그렇지 않다는 것을 확인합니다. @Atul, 이것은 어느 JVM의 것입니까?
wjl

2

주어진 답변은 불변성을 emptyList()반환 List하지만 대안을 제공하지 않는다는 사실을 강조합니다 . 생성자 ArrayList(int initialCapacity)특수 사례 0이므로 new ArrayList<>(0)대신 반환 new ArrayList<>()하는 것이 가능한 솔루션 일 수 있습니다.

/**
 * Shared empty array instance used for empty instances.
 */
private static final Object[] EMPTY_ELEMENTDATA = {};

[...]

/**
 * Constructs an empty list with the specified initial capacity.
 *
 * @param  initialCapacity  the initial capacity of the list
 * @throws IllegalArgumentException if the specified initial capacity
 *         is negative
 */
public ArrayList(int initialCapacity) {
    if (initialCapacity > 0) {
        this.elementData = new Object[initialCapacity];
    } else if (initialCapacity == 0) {
        this.elementData = EMPTY_ELEMENTDATA;
    } else {
        throw new IllegalArgumentException("Illegal Capacity: "+
                                           initialCapacity);
    }
}

(Java 1.8.0_72의 소스)


당신의 접근 방식에 동의하지 않습니다. 초기화시 약간의 메모리와 CPU를 저장하지만 반환 된 목록이 수정 된 경우 목록이 새 배열을 재 할당하는 시간이 줄어 듭니다. 시간이 지남에 따라 많은 요소가 목록에 추가되면 성장 속도가 훨씬 느려 성능 병목 현상이 발생할 수 있습니다. 나는 수정 불가능한 빈 목록 또는 사용 가능하고 수정 가능한 목록의 규칙을 고수하는 것을 선호합니다.
Patrick M

1
내 말로 스트레스를 주려고 시도 했을 때 ( 가능할 수도 있음 ) : 그것은 모두 사용 사례에 달려 있습니다. 나는 일반적으로 것 중 하나를 변경할 수 반환 또는 그들이 비어 있거나없는 어떠했는지에 따라 unmutable 컬렉션,하지 혼합물을. 그리고 "훨씬 더 느린 주장"에 맞서기 위해 : 이것은 현재 구현입니다.
르네

오, JDK 2 메이저 버전이 오래되었다고 해주세요. 따라서 java8은 초기 크기 0에서 기본 용량으로 점프하여 병목 현상을 완전히 피합니다. 죄송합니다.
Patrick M
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.